In general I’m bad at blog anniversaries. I never remember what day I started almost 4 years ago. But 2 posts ago was my 1000th post. Which I think is kinda cool even if the post is a little bit of a throw away. I’ve never been very poignant.
teaser for the new Disney movie The Princess and the Frog
The teaser for the new Disney movie The Princess and the Frog is out but it’s not really getting me very excited even though John Lasseter is in the background somewhere. There is already a lot of controversy around this film as it’s the first black lead in a Disney movie. Is it just me or does the lead just look like a white girl with a medium tan? (via notcot)
Thomas Friedman is a really cheesy speaker.
Thomas Friedman is a really cheesy speaker. I have not read the world is flat and I thought every one had good things to say but if it’s this cheese and built around these fake dates then I don’t want to read it.
Javascript Event onJSReady Fires When All JS Files Have Loaded
Update: jdalton has what looks like a great improvement on my attempt below. Read below to learn about the problem but look at jdalton’s script to see what is now the current best way to implement a solution.
Update (August 5th, 2008): There was an update to the JavaScript below to better handle IE firing off the ready state.
Warning!: Due to a Prototype bug This code is not reliable in any version of IE. This bug is expected to be fixed in Prototype 1.6.0.3.
So the YUI blog had a great post on how javascript blocks downloads and makes the page take longer to load. This is because any JS file can modify the DOM and so the DOM can’t be ready until all JS files have loaded.
Flugpo uses Prototype and not YUI and so to get the speed benefits I needed to build my own Bells and whistles. The problem is that once you load the JS files asynchronously any onDOMReady function will fire before all the JS files download. This is a problem for any inline function calls that have dependencies on other JS files.
Using the Prototype based onDOMReady extension I have created an onJSReady function that checks that all JS files have been loaded. The function needs to know 2 things. How many JS files there are and how many have currently been loaded. When those two number match the even fires and runs any code that is waiting.
/**
* A modified version of Stefan Hayden's onJSReady Prototype plugin.
* http://www.stefanhayden.com/blog/2008/07/29/javascript-event-onjsready-fires-when-all-js-files-have-loaded/
*
* @author John-David Dalton <john.david.dalton[at]gmail[dot]com>
* @usage
* Prototype.include(['test1.js','test2.js','test3.js']); // array
* Prototype.include('test1.js', 'test2.js', 'test3.js'); // separate arguments OR
* Prototype.include('test1.js,test2.js,test3.js'); // comma separated string OR
*
* document.observe('scripts:loaded', function(){ dependent_on_external_js() });
*/
Prototype.include = Object.extend(
function() {
var callee = arguments.callee,
head = document.getElementsByTagName('HEAD')[0],
args = Array.prototype.slice.call(arguments, 0);
args._each(function(files) {
if (Object.isString(files))
files = files.split(',');
callee.total += files.length;
files._each(function(file) {
head.appendChild(
new Element('script', { type: 'text/javascript', src: file.strip() })
)
.observe('readystatechange', function () {
if (!this.loaded && /^(loaded|complete)$/.test(this.readyState)) {
this.loaded = true;
callee.downloaded++;
}
})
.observe('load', function () {
if (this.loaded) return;
this.loaded = true;
callee.downloaded++;
}); // end observers
}); // end files _each
}); // end args _each
},
{
total: 0,
downloaded: 0
}
);
(function() {
var timer;
function ready() {
if (arguments.callee.done) return;
clearInterval(timer);
arguments.callee.done = true;
document.fire('scripts:loaded');
}
timer = setInterval(function() {
var i = Prototype.include;
if (i.total && i.downloaded === i.total) ready();
}, 10);
})();
This is old... ignore this.
window.Total_JS_Files;
window.Downloaded_JS_Files = 0;
function include_js(files) {
var js=new Array();
window.Total_JS_Files = files.length;
for(var i=0; i < files.length; i++) {
var html_doc = document.getElementsByTagName('head')[0];
js[i] = document.createElement('script');
js[i].setAttribute('type', 'text/javascript');
js[i].setAttribute('src', files[i]);
html_doc.appendChild(js[i]);
js[i].onreadystatechange = function () {
if (js[i].readyState == 'complete') {
//alert('JS onreadystate fired ');
window.Downloaded_JS_Files += 1;
}
}
js[i].onload = function () {
//alert('JS onload fired ');
window.Downloaded_JS_Files += 1;
}
}
return false;
}//include_js
Object.extend(Event, {
timeout : function() {
alert('asd');
},
jsReady : function() {
if (arguments.callee.done) {return;}
arguments.callee.done = true;
Event._NreadyCallbacks.each(function(f) { f(); });
Event._NreadyCallbacks = null;
},
onJSReady : function(f) {
if (!this._NreadyCallbacks) {
var jsReady = this.jsReady;
if (jsReady.done) {return f();}
function jsTest() {
if(window.Downloaded_JS_Files == window.Total_JS_Files) {
//setTimeout(jsReady,1);
jsReady();
}
Event._Ntimer = setTimeout(jsTest,1);
}
Event._Ntimer = setTimeout(jsTest,10);
//Event.observe(window, 'load', jsReady);
Event._NreadyCallbacks = [];
}
Event._NreadyCallbacks.push(f);
}
});
To implement this the only JS that needs to load is prototype and these two functions above. Then you just need to load the URLs for the JS files and fire off the include_js function.
var js_paths = new Array;
js_paths[js_paths.length] = '/path/to/js/one.js';
js_paths[js_paths.length] = '/path/to/js/two.js';
js_paths[js_paths.length] = '/path/to/js/three.js';
include_js(js_paths);
Prototype.include(js_paths);
Once all of the JS files have loaded then just like onDOMReady the onJSReady code will fire.
Event.onJSReady(function () { dependent_on_external_js(); });
document.observe('scripts:loaded', function(){ dependent_on_external_js() });
Phil looks like a goofy giant next to Michael Buckley
OMG… Phil looks like a goofy giant next to Michael Buckley. This is totally not photoshoped.