Search

1/04/2008

The window.onload problem (still)

先存下來慢慢看

Peter's Blog - The window.onload problem (still) - 這篇很詳細的解釋了整個經過以及各種不同的嘗試

The YUI YAHOO.util.Event.onContentReady() function solves the problems with onAvailable for some situations. The onContentAvailable() function is similar to onAvailable() but onContentAvailable() declares an element available when it's nextSibling is also found in the DOM. If a nextSibling element is not found then the element is declared available when the window.onload event fires.

Why wait for nextSibling? Suppose in the previous example that we poll the DOM for the unordered list engines element. When this element is found in the DOM it is not necessarily true that all of it's child elements are also in the DOM. The HTML parser may have only parsed the first element in the list and not the rest of the list. If the engines element has a nextSibling existent in the DOM then it is safe to assume that the HTML parser has finished creating the entire list and that all of the list's elements are also available in the DOM. It would take an unreasonably huge amount of paranoia to suspect that browser parsing and DOM construction works any other way.

window.onload: another solution to get it going
window.onload(), DOMContentLoaded, onDocumentReady and document.readystate
window.onload: continued attempt
Dean Edwards's demo and soruce code:
function init() {
// quit if this function has already been called
if (arguments.callee.done) return;

// flag this function so we don't do the same thing twice
arguments.callee.done = true;

// kill the timer
if (_timer) {
clearInterval(_timer);
_timer = null;
}

// create the "page loaded" message
var text = document.createTextNode("Page loaded!");
var message = document.getElementById("message");
message.appendChild(text);
};

/* for Mozilla */
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
var script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
if (this.readyState == "complete") {
init(); // call the onload handler
}
};
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
var _timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
init(); // call the onload handler
}
}, 10);
}

/* for other browsers */
window.onload = init;

以下是prototype用到的code
(function() {
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
Matthias Miller, Dean Edwards and John Resig. */

var timer, fired = false;

function fireContentLoadedEvent() {
if (fired) return;
if (timer) window.clearInterval(timer);
document.fire("dom:loaded");
fired = true;
}

if (document.addEventListener) {
if (Prototype.Browser.WebKit) {
timer = window.setInterval(function() {
if (/loaded|complete/.test(document.readyState))
fireContentLoadedEvent();
}, 0);

Event.observe(window, "load", fireContentLoadedEvent);

} else {
document.addEventListener("DOMContentLoaded",
fireContentLoadedEvent, false);
}

} else {
document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
$("__onDOMContentLoaded").onreadystatechange = function() {
if (this.readyState == "complete") {
this.onreadystatechange = null;
fireContentLoadedEvent();
}
};
}
})();

http://livepipe.net/scripts/code_highlighter.js 用到的code

function asap(fn) {
asap.done ? setTimeout(fn, 0) : asap.waiting.push(fn);
}
asap.waiting = [];
asap.done = 0;
asap.ready = function() {
// (note: deliberately avoids using 'this')
if (!asap.done++) {
asap.timer && clearInterval(asap.timer);
var funcs = asap.waiting;
for (var i = 0, l = funcs.length; i < l; i++) {
setTimeout(funcs[i], 0);
}
}
}
// IE
/*@cc_on@if(@_win32)document.write('<script defer onreadystatechange="readyState==\'complete\'&&asap.ready()" src=//:></script>')@end@*/
// Moz/Op
document.addEventListener && document.addEventListener('DOMContentLoaded', asap.ready, false);
// Safari
asap.timer = navigator.userAgent.match(/WebKit|KHTML/i) && setInterval(function() { document.readyState.match(/loaded|complete/i) && asap.ready() }, 10);
// Fallback
window.onload = asap.ready;

//asap('Syntax.init()');

Update: YUI 的 YAHOO.util.Event.onDOMReady 可以達到一樣的效果.
Update: prototype的寫法

document.observe('dom:loaded', function(){alert('hello')})

DOM加载事件的终极解决方案 - dexter_yy - JavaEye技术网站

沒有留言: