`
huanyq2008
  • 浏览: 171684 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

dom加载完的判断

阅读更多

window.onload事件可以安全的执行javascript,因为该事件是在页面完全加载完后才开始执行(包括页面内的图片、flash等所有元素),不会因为JS需要对某个DOM 操作,而页面还没有加载该节点而引起错误。但是这种安全是需要付出代价的:如果某些图片(或者一些别的东西)加载特别慢,那么load事件会等到很久之后才会触发。针对这个问题,一些JS框架提供了一些补充方法。如:jquery的$(document).ready()、mootools的domready事件。都是在页面的DOM加载完毕后立即执行,而不需要等待漫长的图片下载过程。如果不使用这些框架,可以使用这个独立的DomReady.js

小巧独立的Javascript库:DomReady.js

(function(){

    var DomReady = window.DomReady = {};

	// Everything that has to do with properly supporting our document ready event. Brought over from the most awesome jQuery. 

    var userAgent = navigator.userAgent.toLowerCase();

    // Figure out what browser is being used
    var browser = {
    	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
    	safari: /webkit/.test(userAgent),
    	opera: /opera/.test(userAgent),
    	msie: (/msie/.test(userAgent)) && (!/opera/.test( userAgent )),
    	mozilla: (/mozilla/.test(userAgent)) && (!/(compatible|webkit)/.test(userAgent))
    };    

	var readyBound = false;	
	var isReady = false;
	var readyList = [];

	// Handle when the DOM is ready
	function domReady() {
		// Make sure that the DOM is not already loaded
		if(!isReady) {
			// Remember that the DOM is ready
			isReady = true;
        
	        if(readyList) {
	            for(var fn = 0; fn < readyList.length; fn++) {
	                readyList[fn].call(window, []);
	            }
            
	            readyList = [];
	        }
		}
	};

	// From Simon Willison. A safe way to fire onload w/o screwing up everyone else.
	function addLoadEvent(func) {
	  var oldonload = window.onload;
	  if (typeof window.onload != 'function') {
	    window.onload = func;
	  } else {
	    window.onload = function() {
	      if (oldonload) {
	        oldonload();
	      }
	      func();
	    }
	  }
	};

	// does the heavy work of working through the browsers idiosyncracies (let's call them that) to hook onload.
	function bindReady() {
		if(readyBound) {
		    return;
	    }
	
		readyBound = true;

		// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
		if (document.addEventListener && !browser.opera) {
			// Use the handy event callback
			document.addEventListener("DOMContentLoaded", domReady, false);
		}

		// If IE is used and is not in a frame
		// Continually check to see if the document is ready
		if (browser.msie && window == top) (function(){
			if (isReady) return;
			try {
				// If IE is used, use the trick by Diego Perini
				// http://javascript.nwbox.com/IEContentLoaded/
				document.documentElement.doScroll("left");
			} catch(error) {
				setTimeout(arguments.callee, 0);
				return;
			}
			// and execute any waiting functions
		    domReady();
		})();

		if(browser.opera) {
			document.addEventListener( "DOMContentLoaded", function () {
				if (isReady) return;
				for (var i = 0; i < document.styleSheets.length; i++)
					if (document.styleSheets[i].disabled) {
						setTimeout( arguments.callee, 0 );
						return;
					}
				// and execute any waiting functions
	            domReady();
			}, false);
		}

		if(browser.safari) {
		    var numStyles;
			(function(){
				if (isReady) return;
				if (document.readyState != "loaded" && document.readyState != "complete") {
					setTimeout( arguments.callee, 0 );
					return;
				}
				if (numStyles === undefined) {
	                var links = document.getElementsByTagName("link");
	                for (var i=0; i < links.length; i++) {
	                	if(links[i].getAttribute('rel') == 'stylesheet') {
	                	    numStyles++;
	                	}
	                }
	                var styles = document.getElementsByTagName("style");
	                numStyles += styles.length;
				}
				if (document.styleSheets.length != numStyles) {
					setTimeout( arguments.callee, 0 );
					return;
				}
			
				// and execute any waiting functions
				domReady();
			})();
		}

		// A fallback to window.onload, that will always work
	    addLoadEvent(domReady);
	};

	// This is the public function that people can use to hook up ready.
	DomReady.ready = function(fn, args) {
		// Attach the listeners
		bindReady();
    
		// If the DOM is already ready
		if (isReady) {
			// Execute the function immediately
			fn.call(window, []);
	    } else {
			// Add the function to the wait list
	        readyList.push( function() { return fn.call(window, []); } );
	    }
	};
    
	bindReady();
	
})();

 

使用方法:

<html lang="en"> 
<head> 
    <script src="domready.js" type="application/javascript"></script> 
    <script type="application/javascript"> 
        DomReady.ready(function() { 
            alert('dom is ready'); 
        }); 
    </script> 
</head> 
<body> 
</body> 
</html> 

 

 

 

     jquery里有专门解决DOM加载的函数$(document).ready()(简写就是$(fn)),非常好用!John Resig在《Pro JavaScript Techniques》里,有这样一个方法处理DOM加载,原理就是通过document&& document.getElementsByTagName &&document.getElementById&& document.body 去判断Dom树是否加载完毕。代码如下:

function domReady( f ) {
// 如果DOM加载完毕,马上执行函数
if ( domReady.done ) return f();   
// 假如我们已增加一个函数
if ( domReady.timer ) { 
// 把它加入待执行的函数清单中
domReady.ready.push( f ); 
} else { 
// 为页面加载完成绑定一个事件, 
// 为防止它最先完成. 使用 addEvent(下面列出).
addEvent( window, “load”, isDOMReady );   
// 初始化待执行的函数的数组
domReady.ready = [ f ];   
// 经可能快地检查Dom是否已可用
domReady.timer = setInterval( isDOMReady, 13 ); 

}  
// 检查Dom是否已可操作
function isDOMReady() { 
// 假如已检查出Dom已可用, 忽略 
if ( domReady.done ) return false;   
// 检查若干函数和元素是否可用
if ( document &&  document.getElementsByTagName &&  document.getElementById &&  document.body ) {   
// 假如可用, 停止检查
clearInterval( domReady.timer ); 
domReady.timer = null;   
// 执行所有等待的函数
for ( var i = 0; i < domReady.ready.length; i++ ) 
domReady.ready[i]();   
// 记录在此已经完成
domReady.ready = null; 
domReady.done = true; 

}
// 由 Dean Edwards 在2005 所编写addEvent/removeEvent,
// 由 Tino Zijdel整理
// http://dean.edwards.name/weblog/2005/10/add-event/
//优点是1.可以在所有浏览器工作;
//2.this指向当前元素;
//3.综合了所有浏览器防止默认行为和阻止事件冒泡的的函数
//缺点就是仅在冒泡阶段工作
function addEvent(element, type, handler) {
    // assign each event handler a unique ID
    if (!handler.$$guid) handler.$$guid = addEvent.guid++;
    // create a hash table of event types for the element
    if (!element.events) element.events = {};
    // create a hash table of event handlers for each element/event pair
    var handlers = element.events[type];
    if (!handlers) {
        handlers = element.events[type] = {};
        // store the existing event handler (if there is one)
        if (element["on" + type]) {
            handlers[0] = element["on" + type];
        }
    }
    // store the event handler in the hash table
    handlers[handler.$$guid] = handler;
    // assign a global event handler to do all the work
    element["on" + type] = handleEvent;
};
// a counter used to create unique IDs
addEvent.guid = 1;
function removeEvent(element, type, handler) {
    // delete the event handler from the hash table
    if (element.events && element.events[type]) {
        delete element.events[type][handler.$$guid];
    }
};
function handleEvent(event) {
    var returnValue = true;
    // grab the event object (IE uses a global event object)
    event = event || fixEvent(window.event);
    // get a reference to the hash table of event handlers
    var handlers = this.events[event.type];
    // execute each event handler
    for (var i in handlers) {
        this.$$handleEvent = handlers[i];
        if (this.$$handleEvent(event) === false) {
            returnValue = false;
        }
    }
    return returnValue;
};
function fixEvent(event) {
    // add W3C standard event methods
    event.preventDefault = fixEvent.preventDefault;
    event.stopPropagation = fixEvent.stopPropagation;
    return event;
};
fixEvent.preventDefault = function() {
    this.returnValue = false;
};
fixEvent.stopPropagation = function() {
    this.cancelBubble = true;
};

还有一个估计由几个外国大师合作写的,实现同样功能。

/*
* (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);
    }
})();

分享到:
评论

相关推荐

    JavaScript判断DOM何时加载完毕的技巧

    本文将介绍几种判断DOM加载完毕的技巧,以便开发人员能够在合适的时机执行JavaScript代码。 ### 理解浏览器的渲染和操作顺序 在了解如何判断DOM何时加载完毕之前,首先需要知道浏览器加载网页的一般顺序。通常,...

    vueJs实现DOM加载完之后自动下拉到底部的实例代码

    这篇文章给大家介绍vueJs实现DOM加载完成之后自动下拉到底部,文中给大家记录了整个问题的过程,对实现思路感兴趣的朋友大家阅读下本文。 /……………………………….更新………………………………/ 这个问题是很早...

    基于javascript原生判断DOM是否加载完毕

    这个事件是判断DOM加载状态的理想选择之一。与此相对的是`onload`事件,该事件在页面上所有的内容(包括DOM、样式表、脚本、图片、flash等)都加载完成后触发。 为了在DOM加载完毕后执行代码,可以使用`onReady`...

    C#判断webbrowser页面最终加载完成

    首先,WebBrowser控件提供了一个`DocumentCompleted`事件,当控件加载完一个文档时,这个事件会被触发。但是,需要注意的是,`DocumentCompleted`并不总是意味着所有内容都已经加载完毕,特别是当页面中存在iframe...

    Dom加载让图片加载完再执行的脚本代码

    特别是当页面包含大量图片时,用户可能会在DOM加载完成后就开始浏览,但此时依赖`window.onload`触发的函数还未执行,可能会使某些功能无法正常使用。 为了解决这一问题,我们可以采用一些策略来确保脚本在DOM加载...

    javascript页面加载完执行事件代码

    使用window.onload的优点在于它一次性加载完所有资源后再执行代码,无需再去监听readyState属性的变化。不过,window.onload也有一个缺点,即它只能绑定一个事件处理函数。如果需要在页面加载完毕后执行多个操作,则...

    原生JS实现DOM加载完成马上执行JS代码的方法

    原生JS实现DOM加载完成即执行JS代码的方法主要涉及了JavaScript中页面加载完成事件的捕获和处理,这里我们来详细分解这些方法的实现原理及步骤。 1. **window.onload事件**:window.onload事件会在页面所有的元素,...

    js判断图片加载完成后获取图片实际宽高的方法

    在JavaScript中,传统的做法是通过DOM元素的`.offsetWidth`或`.offsetHeight`属性获取图片的宽度和高度。或者,在使用jQuery时,我们可以用`.width()`和`.height()`方法来获取这些尺寸。然而,这种方法在图片尺寸被...

    DOM和BOM的使用

    onload 函数是指 DOM 中的 onload 事件处理函数,它是在文档加载完成后执行的函数。onload 函数提供了许多方法和属性,开发者可以通过这些方法和属性来操作文档的内容和结构。 查找节点 查找节点是指通过 ...

    DOM与DOM4J的实战操作

    // 删除条件判断 if (node.getNodeName().equals("student")) { Element ele = (Element) node; // 删除特定节点 ele.getParentNode().removeChild(ele); } } } ``` 这段代码演示了如何通过DOM遍历XML文档的...

    js实现页面加载完毕之前loading提示效果

    这样,当页面的DOM结构完全加载完成后,“loading”提示就会自动消失,用户将看到完整的页面内容。这种方法简单有效,能够很好地提升用户体验,尤其是在处理大量数据或者复杂的网页交互时。 总结来说,通过在HTML中...

    JS判断指定dom元素是否在屏幕内的方法实例

    在开发网页的过程中,经常需要判断一个特定的DOM元素是否在当前可视区域内,尤其是在实现图片懒加载或者某些元素的动态加载效果时。本文将详细介绍如何使用JavaScript判断指定的DOM元素是否处于屏幕可视区域之内,并...

    前端开源库-can-use-dom

    `can-use-dom`可以帮助我们判断是否需要加载和初始化这些模拟库。 - **Hybrid应用**:混合移动应用可能在部分场景下运行在无浏览器环境的移动端设备上,检测DOM支持能确保代码的稳定运行。 - **Electron应用**:尽管...

    懒加载,滚动窗口加载,延迟加载js,jquery脚本demo

    jQuery是一个广泛使用的JavaScript库,简化了DOM操作、事件处理以及动画效果,对于实现懒加载这样的功能来说,它提供了方便的API和方法。 懒加载的基本原理是:当用户滚动页面时,检测到特定元素(如图片或脚本)...

    dom4j-1.6.1.jar jaxen.jar

    DOM4J提供了一个基于事件的解析器,可以读取XML文件并将其转换为DOM树,而无需一次性加载整个文档到内存,这在处理大型XML文件时特别有用。此外,DOM4J还支持XPath,这是一种强大的查询语言,可以方便地定位XML文档...

    页面滚动到底部自动加载数据

    在实现滚动加载中,JQuery的`$(window).scroll()`事件监听用户的滚动行为,`$(document).height()`获取文档总高度,`$(window).height()`获取窗口可视区域高度,以及`$(window).scrollTop()`获取滚动条距离顶部的...

    DIV懒加载demo

    例如,我们可以发送Ajax请求获取div的动态内容,然后将内容插入到对应的DOM节点,或者改变div的CSS类以显示隐藏的内容。 4. **优化策略**:为了进一步提高性能,可以采用预加载策略。当一个元素即将进入视口(但还...

Global site tag (gtag.js) - Google Analytics