Adding a script reference into a page using jQuery - javascript

I need to dynamically add a script reference, so I do this:
jQuery('html head').append("<script src='somesource.com/somejs.js'><\/script>")
and it does't work - I don't get any errors but I can't execute any of the methods defined inside that script.
Any ideas what I am doing wrong?

jQuery has a getScript method:
$(document).ready(function() {
$.getScript('somesource.com/somejs.js');
});

Without seeing the script in context, it is hard to say, but possibilities include:
You have the URL wrong (you have what appears to be a domain name, but no protocol in the URI)
You are trying to use the functions without allowing time for the browser to download and run the script (so they aren't defined at the time you call them)

You need a type='text/javascript':
jQuery('html head').append("<script type='text/javascript' src='somesource.com/somejs.js'><\/script>")

Related

How do I use Firebase in an external Javascript file

This is probably a very simple issue, but I've been trying to use Firebase in an external javascript file that is being used with an HTML file and can't get it to work properly. I am planning to use this file for many other similar pages, so I'd rather keep it in an external document. Specifically, my code is:
$(function() {
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.src= 'https://cdn.firebase.com/v0/firebase.js';
head.appendChild(script);
var Database = new Firebase('https://myfirebase.firebaseIO.com/');
...
but when I try to run it, it says that the Firebase object/keyword is undefined. I know that the script is being correctly appended to the HTML page because I've checked the HTML on the page after running the code.
I have also read somewhere that you might need to have a personal server to run Firebase, but frankly I don't really know what that means - in any case, I use Mac OSX and run all of my HTML and Javascript in Chrome.
Thank you very much!
The problem is that using document.createElement does not force the script to be loaded and rendered before your inclusive script is invoked (it's being invoked now). There are no guarantees by this method on when the script you include will get invoked.
Additionally, you are loading the script onDomReady by putting it inside $(function() {...}); you would want to insert it into the header immediately, not wait for the entire document to load.
The simplest answer is to just put Firebase into the head of the html page; you haven't really explained your limitations here, but I assume this isn't an option for you. If it is, KISS.
Another simple answer is to utilize jQuery, since you obviously have it available.
$.getScript('https://cdn.firebase.com/v0/firebase.js', function() {
// now I can use Firebase
});
You can also accomplish this with other methods (wait until Firebase is defined using a setInterval; utilize other script retrieval methods besides document.createElement--try googling "load scripts dynamically via javascript load order"), but I think this covers your needs sufficiently.

Storing shareable embeded javascript for use later

I came accross some embeded javascript, e.g.
<script src="http://player.ooyala.com/player.js?embedCode=5oZDBoMzreLfI78xe1sCSLDmQQFyhXym&deepLinkEmbedCode=5oZDBoMzreLfI78xe1sCSLDmQQFyhXym"></script>
I would like to know how I can execute this dynamically. The reason is, I would like to be able to save the code in a DB and then execute it on the fly later.
I've already tried using $.get with the url and doing an eval on the response with no luck.
I use jQuery if this helps with a solution.
How could I go about this? Thanks.
You're looking for $.getScript("http://player.ooyala.com/player.js?embedCode=5oZDBoMzreLfI78xe1sCSLDmQQFyhXym&deepLinkEmbedCode=5oZDBoMzreLfI78xe1sCSLDmQQFyhXym").
Note that if the script uses document.write, this is impossible.
You can append the entire string to the body using jquery
EDIT: have to escape some characters
$("body").append('\<script src="http://player.ooyala.com/player.js?embedCode=5oZDBoMzreLfI78xe1sCSLDmQQFyhXym&deepLinkEmbedCode=5oZDBoMzreLfI78xe1sCSLDmQQFyhXym"\>\<\/script\>');​
You can use: $.getScript("http://player.ooyala.com/player.js?embedCode=5oZDBoMzreLfI78xe1sCSLDmQQFyhXym&deepLinkEmbedCode=5oZDBoMzreLfI78xe1sCSLDmQQFyhXym&playerContainerId=myplayer")
Note the playerContainerId=myplayer part.
Ooyala has a playerContainerId parameter if you want to add the player as innerHtml of a div and not a document.write().
http://support.ooyala.com/developers/documentation/api/player_examples_qpass.html
You could request it if it supported CORS and then use jQuery's $.globalEval() to evaluate the response - it is executed (from memory) within a script element.
Alternatively, remove the script element on load and then inject it when you want to use it again.

Is it possible to prevent/remove any cached script declared by dojo.require?

I'm encountering an issue where most of a page's main logic is offset in a JS file and initialized within a dojo.require call to simplify debugging and development. We're encountering a case where an offload to another page, and then back to the first one and nothing inside our require script loads. I understand this is due in part to how dojo.require re-uses cached pages, but I can't go back to the cached version either. Is there a way, besides pasting all the scripts inside the page itself, to force Dojo to reload any require regardless of if it has been cached or not?
Force it to be reloaded in HTML.
<script type="text/javascript" src="path/to/my/module/name.js"></script>
<script type="text/javascript">
...
dojo.require("my.module.name");
...
</script>
I don't know if there is any problem on doing it but it does work.
Is there a reason you can't do this the "right" way, by putting the relevant code inside a function and then just calling said function again whenever you want?
If you still think you need to mess with the module loader though I think there are two alternatives after a quick check on the dojo.require source code:
Try to manually clear the module cache
delete d._loadedModules['my.module.name'];
Directly call the internal loader:
var relpath = d._getModuleSymbols(moduleName).join("/") + '.js';
d._loadPath(relpath, null);
(Try these at your own risk)

JavaScript Function Loading

I have a relatively large (in terms of memory use and code size) JS function (running in IE/FF) that I use only occassionally (like, a couple of times per day). I think I can get rid of it when I'm done with it by nulling out its function (using the variable name of the 'function object', as it were).
I am fuzzy though on how I would get it back, supposing maybe some time later I wanted to do it again. How would I load JS on the fly from a URL like the 'script' tag does?
Does this whole line of reasoning make sense?
It's a tad hacky, but there are two ways:
Use DOM methods to insert a script tag into the page to a file that has that function in it. You might need to add a query string so that it thinks it's a new javascript file (like function.js?(random number))
Use AJAX to download the file with the function and eval(); it
The only real way to do this is to insert a script element into the document dynamically using JavaScript with a link to a script file containing your function, causing the script to be loaded. One caveat: you must make sure that the filename has the time appended as a query string, otherwise cache unfriendly browsers like Internet Explorer will not reload the script again.
Like others have said, the best bet is to go ahead and insert a new script tag into the page with some kind of query parameter to avoid caching issues. If you're using a JS Library, this technique is actually called "JSONP"; jQuery in particular has a nice method for doing this that gives you an easy way to attach a callback function and such. If you write your own native version, you'll need to watch the readystate of the new script node to know when it's actually loaded.
That said, one thing I'm curious about - and anyone else, please correct me if I'm wrong - why not use the "delete" keyword to kill your function, instead of nulling it out? Something like...
function myFunction() { return; }
Then...
delete myFunction;
Seems to be a more efficient way of cleaning things up, at least from my perspective.

Problem loading remote script with jQuery multiple times in Firefox

I have a script element in my webpage, something like this:
<script id="myscript"></script>
Now, from a javascript file, I'm doing something like the following:
$('#myscript').src('http://foo.bar?callback=somefunc')
Now this remote script 'returns javascript' of the following form:
somefunc(somearg);
When I run all of this, things work neatly, the script gets loaded dynamically, and the 'somefunc' callback is executed.
The problem happens when I do the same thing again. Let's say I again call the same thing:
$('#myscript').src('http://foo.bar?callback=somefunc')
This, for some reason, DOESNT return the javascript call in Firefox only. (Works fine in IE - somefunc gets executed again as expected).
I can think of ugly workarounds (such as doing a $('head').append('<script...')) every time - but I'd like to know what's going on here.
Thanks in advance!
I would recommend you to use $.getScript instead of using a single script tag load scripts multiple times:
$.getScript("http://foo.bar?callback=somefunc");
That function will abstract the script element creation and its introduction to the DOM.
But it seems you are accessing a JSONP service, in that case you need only $.getJSON:
$.getJSON("http://foo.bar?callback=?", function(json){
// callback
});
I can think of ugly workarounds (such as doing a $('head').append('
Ugliness is subjective; personally, I find the technique you're trying to use (making a single script tag load multiple scripts) far uglier.
But that's not really important. Adding a new script tag works - so if you're having trouble with what you're doing, just use the normal method and live with it.
FWIW: Firefox probably doesn't respond because you're not actually changing anything... If you want to make this even uglier, append some do-nothing querystring parameter that changes each time through.

Categories