源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

模拟jQuery中的ready方法及实现按需加载css,js实例代码

  • 时间:2022-04-23 01:29 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:模拟jQuery中的ready方法及实现按需加载css,js实例代码
[b]一、ready函数的实现 [/b]经常用jQuery类库或其他类库中的ready方法,有时候想想它们到底是怎么实现的,但是看了一下jQuery中的源码,涉及到的模块比较多,(水平有限)代码比较难看懂;自己结合了一些书籍内容,总结一下。 先说一下ready函数的实现思路: 变量ready通过表达式赋值,右侧为一个自执行匿名函数,在这个匿名函数中,首先为各个浏览器的事件绑定处理函数,并为isReady赋值(根据事件异步处理程序来确定),然后返回一个传参闭包,在闭包中,主要判断isReady值来执行操作,如果dom结构准备就绪(isReady === true),执行回调,否则将回调加入到要执行的队列(funs)中,待事件处理程序执行时,循环遍历队列(funs),并依次执行队列中的函数,执行完队列中的函数后,还需要清除队列(funs = null)。
[u]复制代码[/u] 代码如下:
var ready = (function(){     var isReady = false,     funs = [];     function handle (e) {         if ( isReady ) {             return;         }         if ( e.type === 'readystatechange' && (document.readyState !== 'interactive' && document.readyState !== 'complete') ) {             return;         }         for ( var i = 0; i < funs.length; i++ ) {             funs[i].call(document);         }         isReady = true;         funs = null;     }     if ( document.addEventListener ) {         document.addEventListener( 'DOMContentLoaded', handle, false );         document.addEventListener( 'readystatechange', handle, false );         document.addEventListener( 'load', handle, false );     }     else if ( document.attachEvent ) {         document.attachEvent( 'onreadystatechange', handle );         document.attachEvent( 'onload', handle );     }     return function ready (callback) {         if ( isReady ) {             callback.call(document);         }         else {             funs.push(callback);         }     }; }());
PS: 该函数代码参照于权威指南书籍,唯一不同的是,多加了一个判断document.readyState !== 'interactive'
[u]复制代码[/u] 代码如下:
if ( e.type === 'readystatechange' && (document.readyState !== 'interactive' && document.readyState !== 'complete') ) {     return; }
在各个浏览器中交互和完成状态出现顺序并不能保证一致,这取决于浏览器及页面的内容,多加了这个判断document.readyState !== 'interactive'的话, 意思是不管哪个阶段先出现,代码都能更早的执行。 [b]二、按需加载css,js [/b]参照了jQuery源码,写了一个type函数,返回参数类型。
[u]复制代码[/u] 代码如下:
/**  *  * 判断参数类型  * createTime: 2013/9/18  *  */ function type (obj) {     var classTypes, objectTypes;     if ( obj == null ) {         return String(obj);     }     classTypes = {};     objectTypes = ('Boolean Number String Function Array Date RegExp Object Error').split(' ');     for ( var i = 0, len = objectTypes.length; i < len; i++ ) {         classTypes[ '[object ' + objectTypes[i] + ']' ] = objectTypes[i].toLowerCase();     }     if ( typeof obj === 'object' || typeof obj === 'function' ) {         var key = Object.prototype.toString.call(obj);         return classTypes[key];     }     return typeof obj; }
[u]复制代码[/u] 代码如下:
// css按需加载 function loadCss (cssUrl, callback) {     var elem, bl,         isExecuted = false; // 防止在ie9中,callback执行两次     if ( cssUrl == null ) {         return String(cssUrl);     }     elem = document.createElement('link'),     elem.rel = 'stylesheet';     if ( type(callback) === 'function' )  {         bl = true;     }     // for ie     function handle() {         if ( elem.readyState === 'loaded' || elem.readyState === 'complete' ) {             if (bl && !isExecuted) {                 callback();                 isExecuted = true;             }             elem.onreadystatechange = null;         }     }     elem.onreadystatechange = handle;     // for 非ie     if (bl && !isExecuted) {         elem.onload = callback;         isExecuted = true;     }     elem.href = cssUrl;     document.getElementsByTagName('head')[0].appendChild(elem); } // js按需加载 function loadScript(scriptUrl, callback) {     var elem, bl,         isExecuted = false; // 防止在ie9中,callback执行两次     if (scriptUrl == null) {         return String(fn);     }     elem = document.createElement('script');     if ( type(callback) === 'function' )  {         bl = true;     }     // for ie     function handle(){         var status = elem.readyState;         if (status === 'loaded' || status === 'complete') {             if (bl && !isExecuted) {                 callback();                 isExecuted = true;             }             elem.onreadystatechange = null;         }     }     elem.onreadystatechange = handle;     // for 非ie     if (bl && !isExecuted) {         elem.onload = callback;         isExecuted = true;     }     elem.src = scriptUrl;     document.getElementsByTagName('head')[0].appendChild(elem); }
PS: 在判断link,script元素是否加载完毕,主要依靠load事件;而在ie9以下浏览器中,并没有load事件,ie为它们都添加了一个readystatechange事件,通过判断 元素的readyState状态确定元素是否已经加载完毕;而奇怪的是,在ie9(还可能存在其他浏览器版本)中,元素既有load事件又有readystatechange事件,因此在代码中添加了一个变量isExecuted,如果执行过回调,那么就不再执行,避免回调执行两次。 [b]三、调用方式 [/b]
[u]复制代码[/u] 代码如下:
loadCss('http://www.1sucai.cn/apps/tbtx/miiee/css/base.css', function(){     console.log('css加载完毕'); }); loadScript('http://www.1sucai.cn/apps/tbtx/miiee/js/jQuery.js', function(){     console.log('js加载完毕'); }); ready(function(){     console.log('dom is ready!'); });
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部