比windows.onload更早执行的方法
来源:互联网 发布:游戏服务器端编程书籍 编辑:程序博客网 时间:2024/04/27 17:57
最近在学习jQuery,里面牵涉到页面的加载问题,无意中看到这篇文章,觉得很好,估计以后能够用上,特意转贴于下:
原文地址:http://www.cnblogs.com/rubylouvre/archive/2010/04/15/1712780.html
domReady第三版
新的版本放弃使用document.write()(实际上我们依赖的是script标签的defer触发机制),主要基于如下几个理由:
- XHTML不支持document.write
- 当页面上的资源非常少时,会晚于window.onload
- document.write有时会覆写我们原有的DOM
- document.write生成的script不能通过内部函数移除
外国javascript高手Diego Perini于是发掘了doScroll这个方法。在IE下,doScroll方法存在于所有标签。但我搞来搞去,发现光是doScroll也不行,时不时就发现window.onload执行于domReady之前。只有结合onreadystatechange与doScroll这两个方法,我们才能在IE中搞出与标准浏览器相同的结果。因此你在jQuery,Prototype,swfobject,Ext等类库看到它们共同出现。而onreadystatechange其实也有些问题的,具体自己可能google一下,因此2006年左右实现domReady的代码基本依仗于document.write()。嗯,剩下的我就在代码间的注释中说明吧,这样更一目了解。
/*
take from dom library version 1.0, inspired by jQuery
Copyright 2010-2011 (2011.2.27更新)
Dual licensed under the MIT or GPL Version 2 licenses.
author "司徒正美"
http://www.cnblogs.com/rubylouvre/
*/
var
dom = [];
//用于判定页面是否加载完毕
dom.isReady =
false
;
//用于添加要执行的函数
dom.ready =
function
(fn){
if
( dom.isReady ) {
fn()
}
else
{
dom.push( fn );
}
}
//执行所有在window.onload之前放入的函数
dom.fireReady =
function
() {
if
( !dom.isReady ) {
if
( !document.body ) {
return
setTimeout( dom.fireReady, 16 );
}
dom.isReady = 1;
if
( dom.length ) {
for
(
var
i = 0, fn;fn = dom[i];i++)
fn()
}
}
}
//开始初始化domReady函数,判定页面的加载情况
if
( document.readyState ===
"complete"
) {
dom.fireReady();
}
else
if
(-[1,] ){
document.addEventListener(
"DOMContentLoaded"
,
function
() {
document.removeEventListener(
"DOMContentLoaded"
, arguments.callee ,
false
);
dom.fireReady();
},
false
);
}
else
{
//当页面包含图片时,onreadystatechange事件会触发在window.onload之后,
//换言之,它只能正确地执行于页面不包含二进制资源或非常少或者被缓存时
document.attachEvent(
"onreadystatechange"
,
function
() {
if
( document.readyState ==
"complete"
) {
document.detachEvent(
"onreadystatechange"
, arguments.callee );
dom.fireReady();
}
});
(
function
(){
if
( dom.isReady ) {
return
;
}
//doScroll存在于所有标签而不管其是否支持滚动条
//这里如果用document.documentElement.doScroll(),我们需要判定其是否位于顶层document
var
node =
new
Image
try
{
node.doScroll();
node =
null
//防止IE内存泄漏
}
catch
( e ) {
//javascrpt最短时钟间隔为16ms,这里取其倍数
//http://blog.csdn.net/aimingoo/archive/2006/12/21/1451556.aspx
setTimeout( arguments.callee, 64 );
return
;
}
dom.fireReady();
})();
}
<!doctype html><html lang="en"> <head> <meta charset="utf-8" /> <meta content="IE=8" http-equiv="X-UA-Compatible"/> <title>domReady by 司徒正美</title> <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> <title>domReady by 司徒正美</title> <script type="text/javascript"> var dom = []; //用于判定页面是否加载完毕 dom.isReady = false; //用于添加要执行的函数 dom.ready = function(fn){ if ( dom.isReady ) { fn() } else { dom.push( fn ); } } //执行所有在window.onload之前放入的函数 dom.fireReady = function() { if ( !dom.isReady ) { if ( !document.body ) { return setTimeout( dom.fireReady, 16 ); } dom.isReady = 1; if ( dom.length ) { for(var i = 0, fn;fn = dom[i];i++) fn() } } } //开始初始化domReady函数,判定页面的加载情况 if ( document.readyState === "complete" ) { dom.fireReady(); }else if(-[1,] ){ document.addEventListener( "DOMContentLoaded", function() { document.removeEventListener( "DOMContentLoaded", arguments.callee , false ); dom.fireReady(); }, false ); }else { //当页面包含图片时,onreadystatechange事件会触发在window.onload之后, //换言之,它只能正确地执行于页面不包含二进制资源或非常少或者被缓存时 document.attachEvent("onreadystatechange", function() { if ( document.readyState == "complete" ) { document.detachEvent("onreadystatechange", arguments.callee ); dom.fireReady(); } }); (function(){ if ( dom.isReady ) { return; } //doScroll存在于所有标签而不管其是否支持滚动条 //这里如果用document.documentElement.doScroll(),我们需要判定其是否位于顶层document var node = new Image try { node.doScroll(); node = null//防止IE内存泄漏 } catch( e ) { //javascrpt最短时钟间隔为16ms,这里取其倍数 //http://blog.csdn.net/aimingoo/archive/2006/12/21/1451556.aspx setTimeout( arguments.callee, 64 ); return; } dom.fireReady(); })(); } window.onload = function(){ var p = document.createElement("p") p.innerHTML = "window.onload" document.body.appendChild(p); }; dom.ready(function(){ var p = document.createElement("p") p.innerHTML = "domReady1" document.body.appendChild(p); }); dom.ready(function(){ var p = document.createElement("p") p.innerHTML = "domReady2" document.body.appendChild(p); }); </script> </head> <body> <h1>domReady第三版</h1> <p id="p"></p> <h1>加载图片</h1> <p><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/o_s011.jpg"></p> </body></html>
- 比windows.onload更早执行的方法
- 比onload更快的DOMContentLoaded,readystatechange,doscroll的DOM加载事件
- 比onload更快获取图片尺寸的javascript图片预加载技术
- JavaScript执行window.onload和body onload多个处理过程的方法
- JavaScript执行window.onload和body onload多个处理过程的方法
- linux 比Windows更高效
- windows.onload的作用
- 苹果的Tiger 比windows更安全(?)
- windows下比CMD更强大的命令行WMIC
- JS的onload执行顺序
- 方法比知识更重要
- 一个比window.open() 打开更快的方法
- 比阿里巴巴fastjson更快的解析方法!
- $(document).ready()方法与window.onload方法的执行机制的区别
- Android比Windows Phone更适合中国市场
- 著名黑客:Windows比Mac更安全
- 戏说年末盘点后台数据的获取思路------很多时候, 思路比执行更重要!
- 比薪水更重要的 ?
- jsp---->Jsp语法
- mochiweb源码 学习
- C++ IO标准库 文件操作
- 单例模式
- jsp---->包含指令和forward指令
- 比windows.onload更早执行的方法
- mac osx 开机自动运行程序
- 请求WebMethod,Ajax处理更加简练
- Try Catch 概述
- easbos 套打基本配置
- 警惕!移动应用公司正在重蹈1999 覆辙
- jsp---->四种作用域
- redis 数据库 学习
- iframe 页面填充