成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

從jQuery學(xué)到的幾件事情

jlanglang / 2944人閱讀

摘要:最近想看一下源碼,搜到了這樣一篇博客從源碼學(xué)到的件事情本文基于這篇視頻博客,提煉了一些內(nèi)容,分享給大家。的狀態(tài)選擇符,比如存放在里面

最近想看一下jQuery源碼,搜到了這樣一篇博客《從jQuery源碼學(xué)到的10件事情》
http://www.paulirish.com/2010/10-things-i-learned-from-the-jquery-source/

本文基于這篇視頻博客,提煉了一些內(nèi)容,分享給大家。

說(shuō)明:
這篇文章寫(xiě)于2010年,作者在視頻里使用的是jQuery 1.4版本,我根據(jù)視頻里講到的內(nèi)容,對(duì)應(yīng)目前的1字頭1.11版本做了一些調(diào)整,一些被拋棄或者被移除的內(nèi)容頁(yè)做了刪減,并在此感謝原作者h(yuǎn)ttps://github.com/paulirish

黑箱/Black box

黑箱系統(tǒng)的概念是給定輸入返回輸出的一個(gè)系統(tǒng),黑箱把實(shí)現(xiàn)過(guò)程進(jìn)行封裝。這里說(shuō)的jQuery黑箱是為js全局變量window輸出jQuery 和 $,而過(guò)程被封裝到黑箱里,與外界互不干擾。

jQuery 1.4版本的黑箱是利用了類(lèi)似如下的自執(zhí)行函數(shù)

(function( window, undefined){})(window)

作者給了一個(gè)比較通用的實(shí)現(xiàn)黑箱的方法

undefined = true;

(function(window, document, undefined){    
    if(foo == undefined) {
        }
})(this, document)

jQuery的黑箱里多傳了第三個(gè)形參叫做undefined,而傳實(shí)參的時(shí)候并沒(méi)有傳值,js里沒(méi)有傳值的形參會(huì)被設(shè)置為undefined,保證了黑箱內(nèi)部undefined的正確性。js中,undefined作為一個(gè)全局屬性,是可以被賦值的,比如上述代碼中的undefined = true;

以自執(zhí)行函數(shù)的模式實(shí)現(xiàn)黑箱的另外一個(gè)好處是利于壓縮,比如下述的情況,我們只需要在黑箱內(nèi)部使用簡(jiǎn)單的變量。

(function(A, B, C)){
    B.getElementById("")
})(this, document)

作者為匿名函數(shù)自執(zhí)行舉了很多例子,比如下面這個(gè),為頁(yè)面的某一部分不停地更新(以及不斷地執(zhí)行)

(function loop(){
    doStuff();

    $("#update").load("awesomething.php",function(){
        loop();
    })
    //setTimeout(loop, 100)
})()

jQuery 1.11版本的黑箱采用了全新的工廠方法,本文不探究

noConflict的實(shí)現(xiàn)

這個(gè)函數(shù)的差異不大,1.11 版本代碼如下

var
    // Map over jQuery in case of overwrite
    _jQuery = window.jQuery,

    // Map over the $ in case of overwrite
    _$ = window.$;

jQuery.noConflict = function( deep ) {
    if ( window.$ === jQuery ) {
        window.$ = _$;
    }

    if ( deep && window.jQuery === jQuery ) {
        window.jQuery = _jQuery;
    }

    return jQuery;
};

我們可以看到防沖突的實(shí)現(xiàn)是先把之前的JQuery 和 $ 存起來(lái),noConflict被調(diào)用的時(shí)候,再還給它們

與原生js屬性命名的轉(zhuǎn)換

1.4版本用的是props對(duì)象來(lái)存放jquery對(duì)屬性操作與原生js屬性操作的對(duì)應(yīng)關(guān)系
1.11版縮減版本是這樣的

jQuery.extend({
    propFix: {
        "for": "htmlFor",
        "class": "className"
    },

    prop: function( elem, name, value ) {
        //...
        name = jQuery.propFix[ name ] || name;
    },

    propHooks: {
        //...
    }
});

jQuery.each([
    "tabIndex",
    "readOnly",
    "maxLength",
    "cellSpacing",
    "cellPadding",
    "rowSpan",
    "colSpan",
    "useMap",
    "frameBorder",
    "contentEditable"
], function() {
    jQuery.propFix[ this.toLowerCase() ] = this;
});

propFix 這個(gè)對(duì)象是存放對(duì)應(yīng)關(guān)系表的,比如class轉(zhuǎn)換成className,prop函數(shù)負(fù)責(zé)處理這個(gè)關(guān)系表。
而下面的each很有意思,遍歷數(shù)組中那些屬性,然后把他們小寫(xiě)格式對(duì)應(yīng)到自己,放到 propFix

特效Speed

我們知道在jQuery里一些動(dòng)畫(huà)我們可以直接通過(guò)normal,fast,slow 來(lái)定義實(shí)現(xiàn)速度,這個(gè)在源碼里是這樣定義的

jQuery.fx.speeds = {
    slow: 600,
    fast: 200,
    // Default speed
    _default: 400
};

調(diào)皮的原作者做了這樣一些事情:

var isIE 
//...

jQuery.fx.speeds._default = isIE ? 800 : 400
jQuery.fx.speeds.veryfast = 200;

$("...").fadeIn("veryfast")

一種是可以對(duì)default屬性做條件判斷,還有一種自定義速度,比如"veryfast"

.ready

ready函數(shù) 1.11版本和1.4版本有較大的差距,新版中很多東西我也不太能理解,我們就簡(jiǎn)單的把核心拿出來(lái)看一下

jQuery.ready.promise = function( obj ) {
    //...省略若干
        } else if ( document.addEventListener ) {
            // 使用addEventListener "DOMContentLoaded" 監(jiān)聽(tīng)ready事件
            document.addEventListener( "DOMContentLoaded", completed, false );

            // 備選方案 "load"
            window.addEventListener( "load", completed, false );

        //如果IE
        } else {
            // Ensure firing before onload, maybe late but safe also for iframes
                        //IE下 attachEvent 的"onreadystatechange"
            document.attachEvent( "onreadystatechange", completed );

            // A fallback to window.onload, that will always work
                        //備選方案onload
            window.attachEvent( "onload", completed );

            // If IE and not a frame
            // continually check to see if the document is ready
            var top = false;

            try {
                top = window.frameElement == null && document.documentElement;
            } catch(e) {}

            if ( top && top.doScroll ) {
                (function doScrollCheck() {
                    if ( !jQuery.isReady ) {

                        try {
                            // Use the trick by Diego Perini
                            // http://javascript.nwbox.com/IEContentLoaded/
                            top.doScroll("left");
                        } catch(e) {
                            return setTimeout( doScrollCheck, 50 );
                        }

                        // detach all dom ready events
                        detach();

                        // and execute any waiting functions
                        jQuery.ready();
                    }
                })();
            }
        }
    }
    return readyList.promise( obj );
};

.ready 利用了下面的.promise去做確保載入完成的工作,重點(diǎn)是
document.addEventListener( "DOMContentLoaded", completed, false );
window.addEventListener( "load", completed, false );
document.attachEvent( "onreadystatechange", completed );
window.attachEvent( "onload", completed );
兼容性考量的四種檢查方式

其中從top開(kāi)始,做了一件事情就是IE下面,dom節(jié)點(diǎn)判斷是否有scroll,在IE下如果dom有scroll,沒(méi)有scroll到的元素對(duì)ready會(huì)有影響,這里面我的理解不夠,總之jQuery里用到了一個(gè)叫做Diego Perini的技巧,可以在注釋里的地址看到更多內(nèi)容。

選擇器
$("#id").find("tag.thing") --- faster

$("#id tag.thing") ------- using sizzle

原作者在這里說(shuō)了一個(gè)jquery效率的問(wèn)題,上面的方法更快一些,而下面的方法稍微慢,簡(jiǎn)單地說(shuō)是因?yàn)橄旅娴姆椒ㄕ{(diào)用了sizzle,通過(guò)sizzle其實(shí)轉(zhuǎn)換成上述的模式,而id的調(diào)用則是直接過(guò)jQuery.init.

這里需要擴(kuò)展一下,我們來(lái)看一下1.11里jQuery對(duì)象究竟長(zhǎng)啥樣

jQuery = function( selector, context ) {
        // The jQuery object is actually just the init constructor "enhanced"
        // Need init if jQuery is called (just allow error to be thrown if not included)
        return new jQuery.fn.init( selector, context );
}

jQuery對(duì)象其實(shí)是return了一個(gè)它自己的構(gòu)造函數(shù)叫做init,我們?cè)賮?lái)看一下init做了些什么

// Initialize a jQuery object

    init = jQuery.fn.init = function( selector, context ) {
        var match, elem;

        // HANDLE: $(""), $(null), $(undefined), $(false)
            //超級(jí)省略...下略

        // Handle HTML strings

        // HANDLE: $(html) -> $(array)

        // HANDLE: $(html, props)

        // HANDLE: $(#id)

        // HANDLE: $(expr, $(...))

        // HANDLE: $(expr, context)

        // HANDLE: $(DOMElement)

        // HANDLE: $(function)


        return jQuery.makeArray( selector, this );
    };

// Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;

從上面的摘取的代碼注釋中,我們可以看到j(luò)q自己的構(gòu)造函數(shù)里處理了哪些情況,其中包括html標(biāo)簽名和id的獲取,意味著這兩種獲取是最底層的,此外$()的其他處理都要經(jīng)過(guò)其他的函數(shù),效率上不如上述處理情況。
同時(shí)我們也能看到init的原型被賦予了jQuery.fn, 關(guān)于jQuery對(duì)象的相關(guān)內(nèi)容,感興趣的朋友可以再多去了解一些。

jQ的狀態(tài)選擇符,比如:not,:has,:eq存放在
Sizzle.selectors.pseudos里面

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78104.html

相關(guān)文章

  • 這 5 個(gè)前端組件庫(kù),可以讓你放棄 jQuery UI

    摘要:目前正在廣泛使用的框架之一就是。是一系列使用編寫(xiě)的自定義控件,用于創(chuàng)建快速響應(yīng)式的和可擴(kuò)展的控件。的組件主要是使用,并提供了交互式,動(dòng)態(tài)和高度可定制的小部件。例如,演示了如何使用自定義控件,嵌套面板和其它元素。 在建立Web應(yīng)用時(shí),通常都需要用到一些有用的UI組件。無(wú)論應(yīng)用中需要的是日歷,滑塊,圖形或其它用于提升或簡(jiǎn)化用戶交互的組件,那么都面臨兩種選擇:要么自己來(lái)創(chuàng)建這些組件,要么使用...

    1fe1se 評(píng)論0 收藏0
  • 面試集 - 收藏集 - 掘金

    摘要:計(jì)算數(shù)組的極值微信面試題獲取元素的最終前端掘金一題目用代碼求出頁(yè)面上一個(gè)元素的最終的,不考慮瀏覽器,不考慮元素情況。 Excuse me?這個(gè)前端面試在搞事! - 前端 - 掘金金三銀四搞事季,前端這個(gè)近年的熱門(mén)領(lǐng)域,搞事氣氛特別強(qiáng)烈,我朋友小偉最近就在瘋狂面試,遇到了許多有趣的面試官,有趣的面試題,我來(lái)幫這個(gè)搞事 boy 轉(zhuǎn)述一下。 以下是我一個(gè)朋友的故事,真的不是我。 ... ja...

    crossea 評(píng)論0 收藏0
  • 【譯】前端練級(jí)攻略

    摘要:由于系統(tǒng)變得越來(lái)越復(fù)雜,人們提出了稱(chēng)為預(yù)處理器和后處理器的工具來(lái)管理復(fù)雜性。后處理器在由預(yù)處理器手寫(xiě)或編譯后對(duì)應(yīng)用更改。我之前建議的文章,,也涵蓋了預(yù)處理器相關(guān)的知識(shí)。 譯者:前端小智 原文:medium.freecodecamp.org/from-zero-t… medium.freecodecamp.org/from-zero-t… 我記得我剛開(kāi)始學(xué)習(xí)前端開(kāi)發(fā)的時(shí)候。我看到了很多文章及...

    wuyumin 評(píng)論0 收藏0
  • 關(guān)于MQ幾件小事(七)如果讓你設(shè)計(jì)一個(gè)MQ,你怎么設(shè)計(jì)

    摘要:能不能支持?jǐn)?shù)據(jù)丟失啊可以的,參考我們之前說(shuō)的那個(gè)數(shù)據(jù)零丟失方案其實(shí)一個(gè)肯定是很復(fù)雜的,其實(shí)這是個(gè)開(kāi)放題,就是看看你有沒(méi)有從架構(gòu)角度整體構(gòu)思和設(shè)計(jì)的思維以及能力。其實(shí)回答這類(lèi)問(wèn)題,說(shuō)白了,起碼不求你看過(guò)那技術(shù)的源碼,起碼你大概知道那個(gè)技術(shù)的基本原理,核心組成部分,基本架構(gòu)構(gòu)成,然后參照一些開(kāi)源的技術(shù)把一個(gè)系統(tǒng)設(shè)計(jì)出來(lái)的思路說(shuō)一下就好 比如說(shuō)這個(gè)消息隊(duì)列系統(tǒng),我們來(lái)從以下幾個(gè)角度來(lái)考慮一下 (1...

    Vixb 評(píng)論0 收藏0
  • 關(guān)于redis幾件小事(三)redis的數(shù)據(jù)類(lèi)型與使用場(chǎng)景

    摘要:這個(gè)是類(lèi)似的一種結(jié)構(gòu),這個(gè)一般就是可以將結(jié)構(gòu)化的數(shù)據(jù),比如一個(gè)對(duì)象前提是這個(gè)對(duì)象沒(méi)嵌套其他的對(duì)象給緩存在里,然后每次讀寫(xiě)緩存的時(shí)候,可以就操作里的某個(gè)字段。 1.string 這是最基本的類(lèi)型了,就是普通的set和get,做簡(jiǎn)單的kv緩存。 2.hash 這個(gè)是類(lèi)似map的一種結(jié)構(gòu),這個(gè)一般就是可以將結(jié)構(gòu)化的數(shù)據(jù),比如一個(gè)對(duì)象(前提是這個(gè)對(duì)象沒(méi)嵌套其他的對(duì)象)給緩存在redis里,然后每次...

    zhaochunqi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<