I'm writing a script for others to use on their websites. I'd like to use jQuery in this script. Because I don't have control over what frameworks people use on their sites, I need to make sure jQuery is available and that it's version 1.8 or higher. Here's my take on it. Does anyone see anything I could/should be doing differently? Is there a better way of doing this?
//start anon function for whole script
;(function(){
var ,ドル
hasOwn = ({}).hasOwnProperty,
//get ie version returns false if ie>=11 or not ie
ieVersion = function(){
var v = 3,
div = document.createElement('div'),
all = div.getElementsByTagName('i');
while(div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i><![endif]-->', all[0]);
return (v > 4 ? v : ('documentMode' in document ? document.documentMode : false));
}(),
//get which version of jQuery is currently added to the site
jqVersion = function(){
return 'jQuery' in window && !!window.jQuery ? parseFloat(window.jQuery.fn.jquery) : false;
},
//set the correct jquery version to use based on which version of ie is in use. Use an array in the case of one or more being down
jqSrc = (!!ieVersion && ieVersion > 4 && ieVersion < 9) ? ['//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js', '//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js', '//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.0.min.js'] : ['//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js', '//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js', '//ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js'],
//check jquery version and if it is above 1.8 use it, if not then get own version
jqCheck = function(first){
var version = jqVersion();
if(!version || version < 1.8){
getScript(jqSrc.shift(), jqCheck);
}else{
if(!!first){
$ = window.jQuery;
}else{
$ = window.jQuery.noConflict(true);
}
load();
}
},
//function to loop and load jquery script
getScript = function(url, callback){
var script = document.createElement('script'),
tag = document.getElementsByTagName('script')[0],
done = false;
script.type = 'text/javascript';
script.async = !0;
script.src = url;
script.onload = script.onreadystatechange = script.onerror = function(){
if(!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')){
done = true;
if(typeof(callback) === 'function'){
callback.call(this);
}
script.onload = script.onreadystatechange = script.onerror = null;
}
};
tag.parentNode.insertBefore(script, tag);
},
load = function(){
//Start script
window.myGlobalFunction = new function(){
var privateVar = 'private',
privateFunc = function(){
return true;
};
this.publicVar = 'public';
this.publicFunc = function(){
return true;
};
};
};
//make sure json is avaiable, if not add it
if(!hasOwn.call(window, 'JSON') || !hasOwn.call(JSON, 'parse') || (typeof(JSON.parse) !== 'function')){
getScript('//cdnjs.cloudflare.com/ajax/libs/json3/3.3.1/json3.min.js', function(){
//all functions are built start by checking for jQuery and it's builder
jqCheck(true);
});
}else{
//all functions are built start by checking for jQuery and it's builder
jqCheck(true);
}
})();
1 Answer 1
Before actually diving into creating a jQuery checker (nice idea by the way), you might really want to check some cases before building the code. There are several issues with your script here:
Your script assumes that there is jQuery. What if there's no jQuery at all? How would your script work? I suggest you stick to vanilla JS instead.
Documentation too long, didn't read, developer loaded your script first. It will break. You can't detect scripts because they are parsed in order. If your script came first, it cannot see the scripts loaded after it at the point of execution.
But what if a plugin already initialized with the version that came with the page? jQuery carries an internal cache for data, event handlers etc. If you switch jQuery now, they will break.
Dynamically loading a script is an async operation. You can't pause it right there. JS will continue. Therefore, while your script is loading a more recent version, plugins on your page might have already initialized using the one in your page.
Some plugins require a specific version of jQuery (like some prefer 1.4, or 1.6). Developers intentionally use them because some of these plugins use already deprecated API and weren't updated. If you load a newer version, they break.
If you really wanted IE support, why not just load the
1.x
version rather than doing2.x
? This removes the need to detect IE. That's why there's a1.x
and2.x
version in the first place.
-
\$\begingroup\$ Thanks for your feedback. As for the issues: 1. Because of
'jQuery' in window && !!window.jQuery
if there isn't any jQuery at all it will be loaded. 2. This script should be loaded last. If need be I could force it with defer and/or dynamically setting the script to the bottom or start it onwindow.load
. 3. Because of$.noConflict
this shouldn't be an issue at all. 4. I don't see what you're referring to, every call togetScript
is using a callback. Can you please elaborate? 5. As before, not a problem because of$.noConflict
6. I agree, I will removeieVersion
& the 2.0 jQuery. \$\endgroup\$Adam Merrifield– Adam Merrifield2014年04月20日 05:17:25 +00:00Commented Apr 20, 2014 at 5:17
navigator.userAgent
to detect if a browser is IE, what you are doing feels quite hacky and is probably inefficient. Please see stackoverflow.com/questions/5916900/detect-version-of-browser \$\endgroup\$