patternjavascriptMinor
CDN Fallback "library"
Viewed 0 times
cdnfallbacklibrary
Problem
Edit: Even adding a comment of "looks good to me" and up-voting that comment would be appreciated :) I just want the feedback! Thanks!
For the fun of it as well as professional development, I wrote a small "library" (single 24 line JavaScript function) that will allow a developer to double check that all external libraries loaded and to reload them with a local copy as a fallback if the CDN is blocked or down.
Double Take Script Loader
This is a simple way to load a local copy of a library as a fallback to an external CDN.
I'm looking for feedback on my methods. Here's the actual gist on GitHub. Is there any (obvious) way I could improve this function? I realize that everyone has their own style and such. I'm not asking about that. I'm asking about better performance/ease of use. See the specific questions on the lines of code.
dt-script-loader.js
```
var DoubleTakeScriptLoader = function(scripts) { //I have to use the global namespace if I want to let devs call it on their own right?
if (scripts) { //Allows devs to call it with specific scripts
if (Object.prototype.toString.call(scripts) !== '[object Array]' ) { //Is there a better way to check whether it's an array without using another library?
scripts = [scripts]; //Allows devs to call with just an object and I'll change it to an array
}
} else {
scripts = document.getElementsByTagName('script'); //If function is called without argument, we'll get the scripts from the document. I think this will only load the scripts that have been parsed thus far correct?
}
for (var i = 0; i '); //I tried creating a DOM element and adding it to the DOM, but the script wouldn't load. Did I do something wrong, or is this the best way to add a script to the DOM as it is parsing?
if (script.originalId) {
script = document.getElementById(script.originalId);
}
!script.parentNode || script.parentNode.removeChild(script); //Remove the old script. Good/bad?
}
}
For the fun of it as well as professional development, I wrote a small "library" (single 24 line JavaScript function) that will allow a developer to double check that all external libraries loaded and to reload them with a local copy as a fallback if the CDN is blocked or down.
Double Take Script Loader
This is a simple way to load a local copy of a library as a fallback to an external CDN.
I'm looking for feedback on my methods. Here's the actual gist on GitHub. Is there any (obvious) way I could improve this function? I realize that everyone has their own style and such. I'm not asking about that. I'm asking about better performance/ease of use. See the specific questions on the lines of code.
dt-script-loader.js
```
var DoubleTakeScriptLoader = function(scripts) { //I have to use the global namespace if I want to let devs call it on their own right?
if (scripts) { //Allows devs to call it with specific scripts
if (Object.prototype.toString.call(scripts) !== '[object Array]' ) { //Is there a better way to check whether it's an array without using another library?
scripts = [scripts]; //Allows devs to call with just an object and I'll change it to an array
}
} else {
scripts = document.getElementsByTagName('script'); //If function is called without argument, we'll get the scripts from the document. I think this will only load the scripts that have been parsed thus far correct?
}
for (var i = 0; i '); //I tried creating a DOM element and adding it to the DOM, but the script wouldn't load. Did I do something wrong, or is this the best way to add a script to the DOM as it is parsing?
if (script.originalId) {
script = document.getElementById(script.originalId);
}
!script.parentNode || script.parentNode.removeChild(script); //Remove the old script. Good/bad?
}
}
Solution
I like the look of this in general. Its short, simple and I'd love to know how well its worked in the field.
I'm not a big fan of
It comes from http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
In place of the
This uses an ajax request to get the JavaScript instead of blocking your page load. Its all a matter of taste I believe. (Also any other scripts might fail if they are expecting your framework to have loaded.)
After some Google Searching I've found a few places that do the almost same as your framework in less code.
It is shorter but requires one per script file.
I'm not a big fan of
document.write but I don't think the alternative is much better. If you look in the jQuery source code you'll see they eval the script.It comes from http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
In place of the
document.write I might put something like: var xmlHttpReq = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xmlHttpReq.open('GET', localSource);
xmlHttpReq.setRequestHeader('Content-Type', 'application/javascript');
xmlHttpReq.onreadystatechange = function _readyStateChange() {
if (xmlHttpReq.readyState == 4) {
(window.execScript || window.eval).call(window, xmlHttpReq.responseText);
}
}
xmlHttpReq.send(null);This uses an ajax request to get the JavaScript instead of blocking your page load. Its all a matter of taste I believe. (Also any other scripts might fail if they are expecting your framework to have loaded.)
After some Google Searching I've found a few places that do the almost same as your framework in less code.
window.framework || document.write("");It is shorter but requires one per script file.
Code Snippets
var xmlHttpReq = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xmlHttpReq.open('GET', localSource);
xmlHttpReq.setRequestHeader('Content-Type', 'application/javascript');
xmlHttpReq.onreadystatechange = function _readyStateChange() {
if (xmlHttpReq.readyState == 4) {
(window.execScript || window.eval).call(window, xmlHttpReq.responseText);
}
}
xmlHttpReq.send(null);<script src="/path/to/cdn/framwork.js"></script>
<script> window.framework || document.write("<script src=\"/local/path/framework.js\"></script>");</script>Context
StackExchange Code Review Q#28246, answer score: 2
Revisions (0)
No revisions yet.