I have a case where I need to check if jQuery exists on a page and if it doesn't, I need to load it. I create a script tag and reference the external jQuery library. How do I wait for the library to be loaded on the page before I continue with the rest of the script?
UPDATE:
Heres what it looks like after Gion's suggestion:
if (typeof jQuery === 'undefined') {
var j = document.createElement('SCRIPT');
j.type = 'text/javascript';
j.src = '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
document.getElementsByTagName('head')[0].appendChild(j);
j.onload = function () {
var section = document.createElement('DIV');
section.setAttribute('style', 'height:300px; width:250px; position: fixed; right: 0px; top: 100px;z-index: 9999; border-style:solid;border-width:1px;');
section.innerHTML = '<p>steps</p><textarea name="steps"></textarea><p>expected results</p><textarea name="results"></textarea><p><input type="button" name="submit" value="add test case" /></p>';
document.getElementsByTagName('body')[0].appendChild(section);
};
}
<script type="text/javascript">
if(typeof jQuery === 'undefined')
document.write('<sc'+'ript type="text/javascript" src="jquery.js"></scrip'++'t>');
window.onload = function(){
// jquery should be present here
});
</script>
You can check if the jquery is loaded like this
window.onload = function(){
if(typeof jQuery == "undefined"){
// jquery is not available
}
}
And if jquery is not loaded I would recommend using a javascript loader like requirejs http://requirejs.org/
You may set it to window.onload
window.onload = function () { alert("It's loaded!") }
Execute Javascript When Page Has Fully Loaded
to inlcude jQuery file, ONLY if needed, you need to check it first
function afterLoad(){
if(typeof(jQuery)!=='undefined')
return;
var element1 = document.createElement(“script”);
element1.src = “pointToYourjQueryFile.js”;
element1.type=”text/javascript”;
document.getElementsByTagName(“head”)[0].appendChild(element1);
}
call this function on window load this way...
<body onload="afterLoad()"?>
window.onload = function(){
var script,head;
if(!jQuery){
script = document.createElement('script');
document.getElementsByTagName('head')[0].appendChild(script);
script.onload = function(){
alert('jQuery loaded');
}
script.src = 'path_to_jquery';
}
}
Modernizr uses this line:
<script>window.jQuery || document.write('<script src="./js/libs/jquery-1.6.2.min.js"><\/script>')</script>
But document.write is regarded as unsafe. Therefore I'd connect it with what have been posted:
if(!window.jQuery)
{
var element1 = document.createElement(“script”);
element1.src = “somefile.js”;
element1.type=”text/javascript”;
document.getElementsByTagName(“head”)[0].appendChild(element1);
}
On the other hand Google uses:
(function() {
if(window.jQuery) return;
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'some.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
Which appends the script to the first tag already existing on the website. If you have at least one <script> on you site, use this one. From what I know it's considered the best solution.
Related
I have a js file that in which i want to include jquery. in order to include the jquery script i am using this clode:
var script = document.createElement('script');
script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js';
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
this works, I can see that incuded the script correctly. My inspector shows that it loaded the script but jquery wont work.
any ideas?
You need to make sure the script you are dynamically loading is actually loaded before attempting to use it.
To do so, use script.onload to fire a callback once the load is completed.
var script = document.createElement('script');
script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js';
script.type = 'text/javascript';
document.getElementsByTagName('head') [0].appendChild(script);
script.onload = function () {
/* jquery dependent code here */
console.log($);
};
MDN has an example that's more adaptable to a callback you specify -
// from https://developer.mozilla.org/en-US/docs/Web/API/HTMLScriptElement#Dynamically_importing_scripts
function loadError (oError) {
throw new URIError("The script " + oError.target.src + " is not accessible.");
}
function importScript (sSrc, fOnload) {
var oScript = document.createElement("script");
oScript.type = "text\/javascript";
oScript.onerror = loadError;
if (fOnload) { oScript.onload = fOnload; }
document.currentScript.parentNode.insertBefore(oScript, document.currentScript);
oScript.src = sSrc;
}
Your jQuery code is not working may be caused by jQuery is not loaded yet while browser executing your jQuery code. Use function below to dynamically load jQuery with callback. Put your jQuery code inside a callback function.
function loadScript(url, callback) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = url;
if (typeof(callback) === 'function') {
s.onload = s.onreadystatechange = function(event) {
event = event || window.event;
if (event.type === "load" || (/loaded|complete/.test(s.readyState))) {
s.onload = s.onreadystatechange = null;
callback();
}
};
}
document.body.appendChild(s);
}
/* Load up jQuery */
loadScript('https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', function() {
// Put your jQuery code here.
});
You need to include jQuery inside the HTML code. jQuery won't work for you because your script is loaded before jQuery is loaded.
I'm trying to load jquery to page if it's not loaded. I'll run some code right after loading it. With below code, i am trying to catch it when jquery is loaded.
My code loads jquery correctly but not raising onreadystatechange event.
if(typeof jQuery=='undefined') {
var headTag = document.getElementsByTagName("head")[0];
var jqTag = document.createElement('script');
jqTag.type = 'text/javascript';
jqTag.src = 'http://localhost:8001/jquery-min.js';
headTag.appendChild(jqTag);
jqTag.onreadystatechange= function () {
if (this.readyState == 'complete') {
this.loadWidget(containerId);
}
};
}
else {
this.loadWidget(containerId);
}
How can i catch it when jquery is loaded?
script tags have an onload event for when the script has loaded
if (typeof jQuery === 'undefined') {
var headTag = document.getElementsByTagName("head")[0];
var jqTag = document.createElement('script');
jqTag.type = 'text/javascript';
jqTag.onload = function() {
this.loadWidget(containerId);
}
jqTag.src = 'http://localhost:8001/jquery-min.js';
headTag.appendChild(jqTag);
} else {
this.loadWidget(containerId);
}
In my opinion your code is way too complicated.
Why not do what HTML5 boilerplate has done:
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>
If the window.jQuery object isn't detected it elegantly fails over to write out the script tag to include it in native Javascript. You can, of course change the path to whatever you want.
Hope this helps.
Is there a way to load the JavaScript code (without placing it in the very bottom line of HTML document) after the page has been loaded? Here's the script example:
<script type="text/javascript" src="http://www.flickr.com/badge_code_v2.gne?count=10&display=latest&size=t&layout=x&source=user&user=XXX"></script>
PS. the reason is that the above Flickr code loads slowly and hangs the site meanwhile.
you can try it
<script type="text/javascript">
// Use any event to append the code
$(document).ready(function()
{
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "test.js";
// Use any selector
$("head").append(s);
});
</script>
off course this will require jquery library or else you can paste this code on body's onload method
well this is something useful
It's not possible to synchronously execute a script at a URL. Note further that synchronous anything, when networks (or even file systems!) are involved is a Bad Idea. Someone, sometime, somewhere will be on a slow system, or a slow network, or both, and suddenly you've just hung their UI in the process.
http://bugs.jquery.com/ticket/6557
alternatively you can try
http://yepnopejs.com/
Apply it to the body's onload method.
If you want to load a script after the entire page has finished loading (including all the elements) try this. (jQuery)
$(window).load(function() {
var js,
id = 'SCRIPT-ID',
ref = document.getElementsByTagName('script')[0];
if (document.getElementById(id)) {
return;
}
js = document.createElement('script');
js.id = id;
js.async = true;
js.src = "http://www.website.com/script.js";
ref.parentNode.insertBefore(js, ref);
});
If you want it to load once the DOM is rendered, just change $(window) to $(document)
var asyncLoad = function (url) {
if (typeof url !== 'string') {
return false;
}
var script = document.createElement('script'),
firstScript = document.getElementsByTagName('script')[0];
script.setAttribute('src', url);
firstScript.parentNode.insertBefore(script, firstScript);
return script;
};
// or, for scriptless pages, just add to the head;
var asyncLoad = function (url) {
if (typeof url !== 'string') {
return false;
}
var script = document.createElement('script'),
head = document.getElementsByTagName('head')[0];
script.setAttribute('src', url);
head.appendChild(script);
return script;
};
// apply:
document.addEventListener('DOMContentLoaded', function () {
asyncLoad('script_url');
});
If you require modular execution of your scripts you can use following library
http://headjs.com/
I have a initializor.js that contains the following:
if(typeof jQuery=='undefined')
{
var headTag = document.getElementsByTagName("head")[0];
var jqTag = document.createElement('script');
jqTag.type = 'text/javascript';
jqTag.src = 'jquery.js';
headTag.appendChild(jqTag);
}
I am then including that file somewhere on another page. The code checks if jQuery is loaded, and if it isn't, adds it to the Head tag.
However, jQuery is not initializing, because in my main document, I have a few events declared just to test this. I also tried writing some jQuery code below the check, and Firebug said:
"jQuery is undefined".
Is there a way to do this? Firebug shows the jquery inclusion tag within the head tag!
Also, can I dynamically add code into the $(document).ready() event? Or wouldn't it be necessary just to add some Click events to a few elements?
jQuery is not available immediately as you are loading it asynchronously (by appending it to the <head>). You would have to add an onload listener to the script (jqTag) to detect when it loads and then run your code.
e.g.
function myJQueryCode() {
//Do stuff with jQuery
}
if(typeof jQuery=='undefined') {
var headTag = document.getElementsByTagName("head")[0];
var jqTag = document.createElement('script');
jqTag.type = 'text/javascript';
jqTag.src = 'jquery.js';
jqTag.onload = myJQueryCode;
headTag.appendChild(jqTag);
} else {
myJQueryCode();
}
To include jQuery you should use this:
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="jquery.js">\x3C/script>')</script>
it uses the Google CDN but provides a fallback an has a protocol relative URL.
Note: Be sure to change the version number to the latest version
if window.jQuery is defined, it will not continue to read the line since it is an or that already contains a true value, if not it wil (document.)write the value
see: theHTML5Boilerplate
also: you forgot the quotes, if jQuery is not defined:
typeof window.jQuery === "undefined" //true
typeof window.jQuery == undefined //false ,this is wrong
you could also:
window.jQuery === undefined //true
If you're in an async function, you could use await like this:
if(!window.jQuery){
let script = document.createElement('script');
document.head.appendChild(script);
script.type = 'text/javascript';
script.src = "//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js";
await script.onload
}
/* Your jQuery code here */
If you're not, you can use (async function(){/*all the code*/})() to wrap and run all the code inside one
.
Alternatively, refactoring Adam Heath's answer (this is more readable IMO). Bottom line, you need to run the jQuery code AFTER jQuery finished loading.
jQueryCode = function(){
// your jQuery code
}
if(window.jQuery) jQueryCode();
else{
var script = document.createElement('script');
document.head.appendChild(script);
script.type = 'text/javascript';
script.src = "//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js";
script.onload = jQueryCode;
}
Or you could also wrap it in a function to change the order of the code
function runWithJQuery(jQueryCode){
if(window.jQuery) jQueryCode();
else{
var script = document.createElement('script');
document.head.appendChild(script);
script.type = 'text/javascript';
script.src = "//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js";
script.onload = jQueryCode;
}
}
runWithJQuery(function jQueryCode(){
// your jQuery code
})
The YepNope loader can be used to conditionally load scripts, has quite a nice, easy to read syntax, they have an example of just this on their website.
You can get it from their website.
Example taken from their website:
yepnope([{
load: 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js',
complete: function () {
if (!window.jQuery) {
yepnope('local/jquery.min.js');
}
}
}
This site code is solved my problem.
function loadjQuery(url, success){
var script = document.createElement('script');
script.src = url;
var head = document.getElementsByTagName('head')[0],
done = false;
head.appendChild(script);
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function() {
if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
done = true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
}
if (typeof jQuery == 'undefined'){
loadjQuery('http://code.jquery.com/jquery-1.10.2.min.js', function() {
// Write your jQuery Code
});
} else {
// jQuery was already loaded
// Write your jQuery Code
}
http://99webtools.com/blog/load-jquery-if-not-already-loaded/
This is old post but I create one workable solution tested on various places.
Here is the code.
<script type="text/javascript">
(function(url, position, callback){
// default values
url = url || 'https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js';
position = position || 0;
// Check is jQuery exists
if (!window.jQuery) {
// Initialize <head>
var head = document.getElementsByTagName('head')[0];
// Create <script> element
var script = document.createElement("script");
// Append URL
script.src = url;
// Append type
script.type = 'text/javascript';
// Append script to <head>
head.appendChild(script);
// Move script on proper position
head.insertBefore(script,head.childNodes[position]);
script.onload = function(){
if(typeof callback == 'function') {
callback(jQuery);
}
};
} else {
if(typeof callback == 'function') {
callback(jQuery);
}
}
}('https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js', 5, function($){
console.log($);
}));
</script>
Explanation you can find HERE.
Problem:
Load js files asynchronously, then check to see if the dom is loaded before the callback from loading the files is executed.
edit: We do not use jQuery; we use Prototype.
edit: added more comments to the code example.
I am trying to load all of my js files asynchronously so as to keep them from blocking the rest of the page. But when the scripts load and the callback is called, I need to know if the DOM has been loaded or not, so I know how to structure the callback. See below:
//load asynchronously
(function(){
var e = document.createElement('script');
e.type = "text/javascript";
e.async = true;
e.src = srcstr;
// a little magic to make the callback happen
if(navigator.userAgent.indexOf("Opera")){
e.text = "initPage();";
}else if(navigator.userAgent.indexOf("MSIE")){
e.onreadystatechange = initPage;
}else{
e.innerHTML = "initPage();";
}
// attach the file to the document
document.getElementsByTagName('head')[0].appendChild(e);
})();
initPageHelper = function(){
//requires DOM be loaded
}
initPage = function(){
if(domLoaded){ // if dom is already loaded, just call the function
initPageHelper();
}else{ //if dom is not loaded, attach the function to be run when it does load
document.observe("dom:loaded", initPageHelper);
}
}
The callback gets called properly due to some magic behind the scenes that you can learn about from this Google talk: http://www.youtube.com/watch?v=52gL93S3usU&feature=related
What's the easiest, cross-browser method for asking if the DOM has loaded already?
EDIT
Here's the full solution I went with.
I included prototype and the asynchronous script loader using the normal method. Life is just so much easier with prototype, so I'm willing to block for that script.
<script type="text/javascript" src="prototype/prototype.js"></script>
<script type="text/javascript" src="asyncLoader.js"></script>
And actually, in my code I minified the two files above and put them together into one file to minimize transfer time and http requests.
Then I define what I want to run when the DOM loads, and then call the function to load the other scripts.
<script type="text/javascript">
initPage = function(){
...
}
</script>
<script type="text/javascript">
loadScriptAsync("scriptaculous/scriptaculous.js", initPage);
loadScriptAsync("scriptaculous/effects.js", initPage);
loadScriptAsync("scriptaculous/controls.js", initPage);
...
loadScriptAsync("mypage.js", initPage);
</script>
Likewise, the requests above are actually compressed into one httpRequest using a minifier. They are left separate here for readability. There is a snippet at the bottom of this post showing what the code looks like with the minifier.
The code for asyncLoader.js is the following:
/**
* Allows you to load js files asynchronously, with a callback that can be
* called immediately after the script loads, OR after the script loads and
* after the DOM is loaded.
*
* Prototype.js must be loaded first.
*
* For best results, create a regular script tag that calls a minified, combined
* file that contains Prototype.js, and this file. Then all subsequent scripts
* should be loaded using this function.
*
*/
var onload_queue = [];
var dom_loaded = false;
function loadScriptAsync(src, callback, run_immediately) {
var script = document.createElement('script');
script.type = "text/javascript";
script.async = true;
script.src = src;
if("undefined" != typeof callback){
script.onload = function() {
if (dom_loaded || run_immediately)
callback();
else
onload_queue.push(callback);
// clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
};
script.onreadystatechange = function() {
if (script.readyState == 'complete'){
if (dom_loaded || run_immediately)
callback();
else
onload_queue.push(callback);
// clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
}else if(script.readyState == 'loaded'){
eval(script);
if (dom_loaded || run_immediately)
callback();
else
onload_queue.push(callback);
// clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
}
};
}
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
}
document.observe("dom:loaded", function(){
dom_loaded = true;
var len = onload_queue.length;
for (var i = 0; i < len; i++) {
onload_queue[i]();
}
onload_queue = null;
});
I added the option to run a script immediately, if you have scripts that don't rely on the page DOM being fully loaded.
The minified requests actually look like:
<script type="text/javascript" src="/min/?b=javascript/lib&f=prototype/prototype.js,asyncLoader.js"></script>
<script type="text/javascript"> initPage = function(e){...}</script>
<script type="text/javascript">
srcstr = "/min/?f=<?=implode(',', $js_files)?>";
loadScriptAsync(srcstr, initPage);
</script>
They are using the plugin from: [http://code.google.com/p/minify/][1]
What you need is a simple queue of onload functions. Also please avoid browser sniffing as it is unstable and not future proof. For full source code see the [Demo]
var onload_queue = [];
var dom_loaded = false;
function loadScriptAsync(src, callback) {
var script = document.createElement('script');
script.type = "text/javascript";
script.async = true;
script.src = src;
script.onload = script.onreadystatechange = function() {
if (dom_loaded)
callback();
else
onload_queue.push(callback);
// clean up for IE and Opera
script.onload = null;
script.onreadystatechange = null;
};
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
}
function domLoaded() {
dom_loaded = true;
var len = onload_queue.length;
for (var i = 0; i < len; i++) {
onload_queue[i]();
}
onload_queue = null;
};
// Dean's dom:loaded code goes here
// do stuff
domLoaded();
Test usage
loadScriptAsync(
"http://code.jquery.com/jquery-1.4.4.js",
function() {
alert("script has been loaded");
}
);
You can always put your initial loader script at the bottom, right before the closing body tag.