Talk:Useful include function

From The WebGL Cookbook
Jump to: navigation, search

Im sorry if i have miss spelled any thing, im amazed if i havent. Maybe it should say import instead of include and it should definitely support shaders.

dose any body have a good idea for a good way for that?

I'm thinking add tag and fetch source code later and setting the id of the script tag to the name of the file(without the ending).

--Neppord 04:44, 13 November 2009 (UTC)




The problem with this is that the scripts are fetched asynchronously, so you can't depend on the include()'ed libraries because you don't know when they have finished loading.

A more complete solution would be to require a parameter passed to the include method called "watch". The include method would poll for a variable in the global scope to determine if the library has finished loading yet. The third parameter would then be a callback function that gets executed once the "watch" variable is detected.

Something like:

var include = (function() {
var included = [],
head,
defaultTimeout = 10;
function log(type,message) {
window.console && window.console[type || 'log'](Array.prototype.join.apply(Array.prototype.slice.apply(arguments,[1]),[' ']));
}
return function (url, watch, callback, timeout) {
var element,
check,
startTime = new Date().getTime();
 
callback = callback || function(){};
 
if (included.indexOf(url)>-1) {
log('warn', "Duplicate include, skipping:", url);
callback(true);
return true;
}
included.push(url);
 
switch (url.split(".").pop()) {
case "css":
element = document.createElement("link");
element.setAttribute("rel", "stylesheet");
element.setAttribute("type", "text/css");
element.setAttribute("href", url);
break;
case "js":
element = document.createElement("script");
element.setAttribute("type", "text/javascript");
element.setAttribute("src", url);
break;
default:
log('error', "could not identify", url, "skip include");
return;
}
if (!head) {
head = document.getElementsByTagName("head");
head = head && head[0];
}
if (head) {
head.appendChild(element);
}
 
if (watch) {
check = function() {
if (window.hasOwnProperty(watch)) {
callback(true);
check = element = null;
}
else if (new Date().getTime()-startTime>(timeout || defaultTimeout)*1000) {
log('error', "include('",url,"') timed out");
callback(false);
element.parentNode.removeChild(element);
check = element = null;
}
else {
setTimeout(check, 50);
}
};
setTimeout(check, 50);
}
};
}());


Here is a test that shows where the original include() function fails, and where my version works as intended:

include("http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",'jQuery',function() {
// because the callback was fired once the library loaded, window.jQuery should now be defined.
alert("In the callback, jQuery is " + window.jQuery + " \n\n(should be defined)");
});
 
// trying to use window.jQuery immediately after include() won't work unless the library has already been loaded and cached.
alert("Immediately after the include, jQuery is " + window.jQuery + " \n\n(should be undefined)");

Also note that my method doesn't touch the DOM to check for previously loaded libraries, which prevents unnecessary reflows.

--Developit 17:46, 7 July 2010 (UTC)

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox