DOM加载完成后执行js(javascript)代码

要求js代码是在Dom加载完毕后执行,而不是所有web元素加载完毕。之所以不用onload,是因为onload只能添加1次有效,自己绑事件太麻烦。并且onload是所有元素加载完毕后触发。恨死IE了,没有DOMContentLoaded之类的事件。
 
jquery的ready()不错,但是太大不想用,就在网上找到一份传说中能兼容所有浏览器的可以追加onload的代码,经过测试发现IE6下面某些网页还是有问题,初步估计可能是网站利用了Ajax修改Dom导致的,最近没时间细看,先贴出来以后修改一下。
用法如下:
1  FP_DomLoaded.load(yourFunction);
2  FP_DomLoaded.load(function(){
alert(‘http://www.fengpiaoyu.com’);
});
代码如下:
var FP_DomLoaded =
{
onload: [],
loaded: function()
{
if (arguments.callee.done) return;
arguments.callee.done = true;
for (i = 0;i < FP_DomLoaded.onload.length;i++) FP_DomLoaded.onload[i]();
},
load: function(fireThis)
{
this.onload.push(fireThis);
if (document.addEventListener)
document.addEventListener(“DOMContentLoaded”, FP_DomLoaded.loaded, null);
if (/KHTML|WebKit/i.test(navigator.userAgent))
{
var _timer = setInterval(function()
{
if (/loaded|complete/.test(document.readyState))
{
clearInterval(_timer);
delete _timer;
FP_DomLoaded.loaded();
}
}, 10);
}
/*@cc_on @*/
/*@if (@_win32)
var proto = “src=’javascript:void(0)’”;
if (location.protocol == “https:”) proto = “src=//0″;
document.write(“<scr”+”ipt id=__ie_onload defer ” + proto + “><\/scr”+”ipt>”);
var script = document.getElementById(“__ie_onload”);
script.onreadystatechange = function() {
if (this.readyState == “complete”) {
FP_DomLoaded.loaded();
}
};
/*@end @*/
window.onload = FP_DomLoaded.loaded;
}
};
下面还有一个从jquery里提取出来的ready,不过我没测试过,先贴出来:
(function(){
var isReady=false; //判断onDOMReady方法是否已经被执行过
var readyList= [];//把需要执行的方法先暂存在这个数组里
var timer;//定时器句柄
ready=function(fn) {
if (isReady )
fn.call( document);
else
readyList.push( function() { return fn.call(this);});
return this;
}
var onDOMReady=function(){
for(var i=0;i<readyList.length;i++){
readyList[i].apply(document);
}
readyList = null;
}
var bindReady = function(evt){
if(isReady) return;
isReady=true;
onDOMReady.call(window);
if(document.removeEventListener){
document.removeEventListener(“DOMContentLoaded”, bindReady, false);
}
else if(document.attachEvent){
document.detachEvent(“onreadystatechange”, bindReady);
if(window == window.top){
clearInterval(timer);
timer = null;
}
}
};
if(document.addEventListener){
document.addEventListener(“DOMContentLoaded”, bindReady, false);
}else if(document.attachEvent){
document.attachEvent(“onreadystatechange”, function(){
if((/loaded|complete/).test(document.readyState))
bindReady();
});
if(window == window.top){
timer = setInterval(function(){
try{
isReady||document.documentElement.doScroll(‘left’);//在IE下用能否执行doScroll判断 dom是否加载完毕
}catch(e){
return;
}
bindReady();
},5);
}
}
})();
使用方法:
ready(dosomething);//dosomething为已存在的函数
//也可以通过闭包来使用
ready(function(){
alert(‘http://www.fengpiaoyu.com’);
});
这个代码也是网上据说从jquery提取的,但个人觉得有点那个,,代码用doScroll来判断IE的DOM是否加载完成,因为DOM未加载完成时调用doScroll方法,会产生异常。但是如果某天IE不报异常了呢?改天有空研究下jquery的代码再说。
再贴一个,有点类似第一个:
/*
* (c)2006 Jesse Skinner/Dean Edwards/Matthias Miller/John Resig
* Special thanks to Dan Webb’s domready.js Prototype extension
* and Simon Willison’s addLoadEvent
*
* For more info, see:
* http://www.thefutureoftheweb.com/blog/adddomloadevent
* http://dean.edwards.name/weblog/2006/06/again/
* http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype
* http://simon.incutio.com/archive/2004/05/26/addLoadEvent
*
*
* To use: call addDOMLoadEvent one or more times with functions, ie:
*
* function something() {
* // do something
* }
* addDOMLoadEvent(something);
*
* addDOMLoadEvent(function() {
* // do other stuff
* });
*
*/

addDOMLoadEvent = (function(){
// create event function stack
var load_events = [],
load_timer,
script,
done,
exec,
old_onload,
init = function () {
done = true;

// kill the timer
clearInterval(load_timer);

// execute each function in the stack in the order they were added
while (exec = load_events.shift())
exec();

if (script) script.onreadystatechange = ”;
};

return function (func) {
// if the init function was already ran, just run this function now and stop
if (done) return func();

if (!load_events[0]) {
// for Mozilla/Opera9
if (document.addEventListener)
document.addEventListener(“DOMContentLoaded”, init, false);

// for Internet Explorer
/*@cc_on @*/
/*@if (@_win32)
document.write(“<script id=__ie_onload defer src=//0><\/scr”+”ipt>”);
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
load_timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState))
init(); // call the onload handler
}, 10);
}

// for other browsers set the window.onload, but also execute the old window.onload
old_onload = window.onload;
window.onload = function() {
init();
if (old_onload) old_onload();
};
}

load_events.push(func);
}
})();

原文地址:https://www.cnblogs.com/Mygirl/p/2236491.html