云建站自动建站系统源码,Wordpress做APP后端,阿里巴巴网站怎么做推广方案,wordpress 随机显示基于jQuery v1.8.3
在js与DOM交互之前要确保DOM已经加载构建完成#xff0c;在jQuery中都是使用 (fn)或者(document).ready(fn)来确保自己写的代码在DOM构建完成之后执行。 那么jQuery的ready事件内部怎么实现的呢#xff1f;
通过阅读源码#xff08;line:842 ~ 898在jQuery中都是使用 (fn)或者(fn) 或者 (document).ready(fn)来确保自己写的代码在DOM构建完成之后执行。 那么jQuery的ready事件内部怎么实现的呢
通过阅读源码line:842 ~ 898知道jQuery内部使用四种判别文档是否加载完成的事件
DOMContentLoaded 初始的 HTML 文档被完全加载和解析完成之后DOMContentLoaded 事件被触发而无需等待样式表、图像和子框架的完成加载load 一个页面完全加载之后触发readyStateChange 文档加载状态document.readyState改变的时候触发当document.readyState ‘complete’ 为 true 表示文档解析完成。 readyState可能的值有 1. loading 加载2. interactive 互动3. complete 完成
doScroll 低版本IE支持的事件如果调用不出错就表示文档解析完成
部分源码如下
/**
*先检查一下文档是否加载完成了如果执行这个方法的时候文档已经加载完成还不知道就尴尬了。。。后面注册的监听文档是否加载完成的事件都不会被触发
*因为我们都知道事件的特性就是错过了就是错过了
*/
if ( document.readyState complete ) {setTimeout( jQuery.ready, 1 );
} else if ( document.addEventListener ) {// 检测是否支持 DOMContentLoaded该事件这是H5新加的事件在DOM结构构件完成触发不会等待资源的下载如IMG等所以会比window.onload提前触发document.addEventListener( DOMContentLoaded, DOMContentLoaded, false );// 监听onload事件window.addEventListener( load, jQuery.ready, false );
} else {// 这里是低版本的IE浏览器// 通过attachEvent监听readystatechange和load事件document.attachEvent( onreadystatechange, DOMContentLoaded );window.attachEvent( onload, jQuery.ready );// 在顶层不在iframe里面var top false;try {top window.frameElement null document.documentElement;} catch(e) {}if ( top top.doScroll ) {(function doScrollCheck() {if ( !jQuery.isReady ) {try {top.doScroll(left);} catch(e) {return setTimeout( doScrollCheck, 50 );}jQuery.ready();}})();}
通过以上源码分析自己来实现一个完整的
需求
确保代码会在文档加载完的第一时间被调用
可以正确处理多次调用调用多次ready(fn); ready(fn)
(function(window, undefined){// 任务队列var PENDING pending,COMPLETE complete,first true, // 第一次调用ready方法queue [],state PENDING; // pending complatevar obser {queue: [],fire: function(){while(this.queue.length){this.queue.shift()();}},add: function(fn){this.queue.push(fn);}};function loaded(){// 防止被触发多次if(state COMPLETE) return;if(document.addEventListener){state COMPLETE;obser.fire();document.removeEventListener(DOMContentLoaded, loaded, false);window.removeEventListener(load, loaded, false);}else if(document.readyState complete){// 这里必须要是 document.readyState complate 才行state COMPLETE;obser.fire();document.detachEvent(DOMContentLoaded, loaded);window.detachEvent(load, loaded);}}function ready(fn){if(first){// 如果是第一次调用顺待要注册一下事件if(document.readyState complete){loaded();}else if(document.addEventListener){document.addEventListener(DOMContentLoaded, loaded, false);window.addEventListener(load, loaded, false);}else{// 这里处理IEdocument.attachEvent(onreadystatechange, loaded);window.attachEvent(onload, loaded);}}if(state COMPLETE){fn();}else{obser.add(fn);}}window.ready ready;
})(window, undefined);// 之后直接调用ready(fn)即可