亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

模擬jQuery中的ready方法及實現(xiàn)按需加載css,js實例代碼

 更新時間:2013年09月27日 16:18:12   投稿:shangke  
這篇文章介紹了模擬jQuery中的ready方法及實現(xiàn)按需加載css,js實例代碼,有需要的朋友可以參考一下

一、ready函數(shù)的實現(xiàn)經(jīng)常用jQuery類庫或其他類庫中的ready方法,有時候想想它們到底是怎么實現(xiàn)的,但是看了一下jQuery中的源碼,涉及到的模塊比較多,(水平有限)代碼比較難看懂;自己結(jié)合了一些書籍內(nèi)容,總結(jié)一下。
先說一下ready函數(shù)的實現(xiàn)思路:
變量ready通過表達(dá)式賦值,右側(cè)為一個自執(zhí)行匿名函數(shù),在這個匿名函數(shù)中,首先為各個瀏覽器的事件綁定處理函數(shù),并為isReady賦值(根據(jù)事件異步處理程序來確定),然后返回一個傳參閉包,在閉包中,主要判斷isReady值來執(zhí)行操作,如果dom結(jié)構(gòu)準(zhǔn)備就緒(isReady === true),執(zhí)行回調(diào),否則將回調(diào)加入到要執(zhí)行的隊列(funs)中,待事件處理程序執(zhí)行時,循環(huán)遍歷隊列(funs),并依次執(zhí)行隊列中的函數(shù),執(zhí)行完隊列中的函數(shù)后,還需要清除隊列(funs = null)。

復(fù)制代碼 代碼如下:

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:
該函數(shù)代碼參照于權(quán)威指南書籍,唯一不同的是,多加了一個判斷document.readyState !== 'interactive'
復(fù)制代碼 代碼如下:

if ( e.type === 'readystatechange' && (document.readyState !== 'interactive' && document.readyState !== 'complete') ) {
    return;
}

在各個瀏覽器中交互和完成狀態(tài)出現(xiàn)順序并不能保證一致,這取決于瀏覽器及頁面的內(nèi)容,多加了這個判斷document.readyState !== 'interactive'的話,
意思是不管哪個階段先出現(xiàn),代碼都能更早的執(zhí)行。
二、按需加載css,js
參照了jQuery源碼,寫了一個type函數(shù),返回參數(shù)類型。
復(fù)制代碼 代碼如下:

/**
 *
 * 判斷參數(shù)類型
 * 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;
}

復(fù)制代碼 代碼如下:

// css按需加載
function loadCss (cssUrl, callback) {
    var elem, bl,
        isExecuted = false; // 防止在ie9中,callback執(zhí)行兩次
    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執(zhí)行兩次
    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: 在判斷l(xiāng)ink,script元素是否加載完畢,主要依靠load事件;而在ie9以下瀏覽器中,并沒有l(wèi)oad事件,ie為它們都添加了一個readystatechange事件,通過判斷
元素的readyState狀態(tài)確定元素是否已經(jīng)加載完畢;而奇怪的是,在ie9(還可能存在其他瀏覽器版本)中,元素既有l(wèi)oad事件又有readystatechange事件,因此在代碼中添加了一個變量isExecuted,如果執(zhí)行過回調(diào),那么就不再執(zhí)行,避免回調(diào)執(zhí)行兩次。
三、調(diào)用方式
復(fù)制代碼 代碼如下:

loadCss('//chabaoo.cn/apps/tbtx/miiee/css/base.css', function(){
    console.log('css加載完畢');
});
loadScript('//chabaoo.cn/apps/tbtx/miiee/js/jQuery.js', function(){
    console.log('js加載完畢');
});
ready(function(){
    console.log('dom is ready!');
});

相關(guān)文章

最新評論