返回首页

Javascript封装DOMContentLoaded事件实现教程

时间:2014-03-31 01:58来源:知行网www.zhixing123.cn 编辑:麦田守望者

最近在写一个Javascript的框架,刚把DOMContentLoaded事件封装好,略带小兴奋,把开发过程中遇到的原理和兼容性问题做篇笔记,省的忘记到处找。

 

我们在写js代码的时候,一般都会添加window.onload事件,主要是为了在DOM加载完后可以使用getElementById,getElementsByTagName等方法选取DOM元素进行操作,但是window.load会等到加载完DOM、脚本、CSS,最后加载完图片甚至是iframe中的所有资源才会触发,很多时候网页的图片较多较大,要等最后图片这个耗时大户加载完才执行js明显有些太迟了,很多时候都会影响用户体验。

很多js框架都有个document.ready的功能,像JQuery的$(document).ready()方法,可以在DOM加载完就立即执行js代码,让图片自个慢慢加载吧。

document.ready的核心是DOMContentLoaded事件,firefox、chrome、opera、safari、ie9+都可以使用addEventListener(‘DOMContentLoaded’,fn,false)进行事件绑定,而ie6~8不支持DOMContentLoaded事件,所以要针对ie6~8做兼容性处理。

资料上说ie6~8可以使用document.onreadystatechange事件监听document.readyState状态是否等于complete来判断DOM是否加载完毕,如果页面中嵌有iframe的话,ie6~8的document.readyState会等到iframe中的所有资源加载完才会变成complete,此时iframe变成了耗时大户。但是经过测试,即使页面中没有iframe,当readyState等于complete时,实际触发的是onload事件而不是DOMContentLoaded事件,对这点表示惊奇。

还好ie有个特有的doScroll方法,当页面DOM未加载完成时,调用doScroll方法时,就会报错,反过来,只要一直间隔调用doScroll直到不报错,那就表示页面DOM加载完毕了,不管图片和iframe中的内容是否加载完毕,此法都有效。

如果有多个js文件绑定了document.ready事件,为了防止浏览器重复绑定,同时有序执行,可以引入一个事件队列机制来解决。

以上就是document.ready事件的原理和兼容性问题,下面贴段实例代码,为了方便理解执行过程,使用函数封装的模式,执行过程都写在注释里了,如果有不妥之处欢迎指教。

	//保存domReady的事件队列
	eventQueue = [];

	//判断DOM是否加载完毕
	isReady = false;

	//判断DOMReady是否绑定
	isBind = false;

	/*执行domReady()
	 *
	 *@param    {function}
	 *@execute  将事件处理程序压入事件队列,并绑定DOMContentLoaded
	 *			如果DOM加载已经完成,则立即执行
	 *@caller
	 */
	function domReady = function(fn){
		if (isReady) {
			fn.call(window);
		}
		else{
			eventQueue.push(fn);
		};

		bindReady();
	};

	/*domReady事件绑定
	 *
	 *@param    null
	 *@execute  现代浏览器通过addEvListener绑定DOMContentLoaded,包括ie9+
	 			ie6-8通过判断doScroll判断DOM是否加载完毕
	 *@caller   domReady()
	 */
	function bindReady = function(){
		if (isReady) return;
		if (isBind) return;
		isBind = true;

		if (window.addEventListener) {
			document.addEventListener('DOMContentLoaded',execFn,false);
		}
		else if (window.attachEvent) {
			doScroll();
		};
	};

	/*doScroll判断ie6-8的DOM是否加载完成
	 *
	 *@param    null
	 *@execute  doScroll判断DOM是否加载完成
	 *@caller   bindReady()
	 */
	function doScroll = function(){
		try{
			document.documentElement.doScroll('left');
		}
		catch(error){
			return setTimeout(doScroll,20);
		};
		execFn();
	};

	/*执行事件队列
	 *
	 *@param    null
	 *@execute  循环执行队列中的事件处理程序
	 *@caller   bindReady()
	 */
	function execFn = function(){
		if (!isReady) {
			isReady = true;
			for (var i = 0; i < eventQueue.length; i++) {
				eventQueue[i].call(window);
			};
			eventQueue = [];
		};
	};

	//js文件1
	domReady(function(){
		...
	});
	//js文件2
	domReady(function(){
		...
	});

	//注意,如果是异步加载的js就不要绑定domReady方法,不然函数不会执行,
	//因为异步加载的js下载之前,DOMContentLoaded已经触发,addEventListener执行时已经监听不到了

测试页面:都加载了两张很大的图片,onload需要图片加载完才能执行js,DOMContentLoaded只需等到DOM加载完即可执行js。可以打开firebug查看加载过程,每次测试前记得先清理下浏览器缓存。

------分隔线----------------------------
标签(Tag):Javascript javascript龙8国际平台入口 JavaScript源代码 JavaScript基础教程
------分隔线----------------------------
推荐内容
  • 如何安装oracle 10g数据库 oracle 10g安装图解

    特意为大家制作了一份 oracle 10g安装图解 ,这样大家在安装的时候就不会出错了,至于...

  • Eclipse 如何安装Spring IDE支持

    ECLIPSE ARCHIVE离线安装包 SIZE 4.6 springsource-tool-suite-3.8.1.RELEASE-e4.6-up...

  • Eclipse 初始设置图解教程

    一、自动补全 .abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 二、字体设置 ...

  • idear如何配置JRebel实现热部署

    习惯写PHP之后,发现写JavaEE最蛋疼的是每次修改完代码,需要重启Tomcat服务,当项目...

  • java常用设计模式原型模式及深浅拷贝

    原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的...

  • java中单例模式的4种实现方式

    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式...

  • 猜你感兴趣
  • 教育技术学动态
  • 教育技术学论文
  • 理论研究
  • 应用研究
  • 资源收藏
  • 百家观点
  • 英文文献
  • 中国电化教育
  • 电化教育研究
  • 中国远程教育
  • 开放教育研究
  • 现代教育技术
  • 远程教育杂志
  • 现代远距离教育
  • 中国教育信息化
  • 中国信息技术教育
  • 中小学信息技术
  • Flash龙8国际平台入口
  • Photoshop龙8国际平台入口
  • 3DMAX龙8国际平台入口
  • AutoCAD龙8国际平台入口
  • CorelDRAW龙8国际平台入口
  • Matlab龙8国际平台入口
  • 其他龙8国际平台入口
  • .Net龙8国际平台入口
  • Asp龙8国际平台入口
  • Php龙8国际平台入口
  • Jsp龙8国际平台入口
  • Ajax龙8国际平台入口
  • Android教程
  • 其他龙8国际平台入口
  • Word教程
  • Excel教程
  • PowerPoint教程
  • Ubuntu教程
  • 其他教程
  • 课件下载
  • 软件下载
  • 视频教程下载
  • 其他下载
  • 教案大全
  • 试题大全
  • 课件大全
  • 其他大全
  • 人像摄影
  • 风光摄影