摘要:最近想看一下源碼,搜到了這樣一篇博客從源碼學到的件事情本文基于這篇視頻博客,提煉了一些內(nèi)容,分享給大家。的狀態(tài)選擇符,比如存放在里面
最近想看一下jQuery源碼,搜到了這樣一篇博客《從jQuery源碼學到的10件事情》
http://www.paulirish.com/2010/10-things-i-learned-from-the-jquery-source/
本文基于這篇視頻博客,提煉了一些內(nèi)容,分享給大家。
說明:
這篇文章寫于2010年,作者在視頻里使用的是jQuery 1.4版本,我根據(jù)視頻里講到的內(nèi)容,對應目前的1字頭1.11版本做了一些調(diào)整,一些被拋棄或者被移除的內(nèi)容頁做了刪減,并在此感謝原作者https://github.com/paulirish
黑箱系統(tǒng)的概念是給定輸入返回輸出的一個系統(tǒng),黑箱把實現(xiàn)過程進行封裝。這里說的jQuery黑箱是為js全局變量window輸出jQuery 和 $,而過程被封裝到黑箱里,與外界互不干擾。
jQuery 1.4版本的黑箱是利用了類似如下的自執(zhí)行函數(shù)
(function( window, undefined){})(window)
作者給了一個比較通用的實現(xiàn)黑箱的方法
undefined = true; (function(window, document, undefined){ if(foo == undefined) { } })(this, document)
jQuery的黑箱里多傳了第三個形參叫做undefined,而傳實參的時候并沒有傳值,js里沒有傳值的形參會被設置為undefined,保證了黑箱內(nèi)部undefined的正確性。js中,undefined作為一個全局屬性,是可以被賦值的,比如上述代碼中的undefined = true;
以自執(zhí)行函數(shù)的模式實現(xiàn)黑箱的另外一個好處是利于壓縮,比如下述的情況,我們只需要在黑箱內(nèi)部使用簡單的變量。
(function(A, B, C)){ B.getElementById("") })(this, document)
作者為匿名函數(shù)自執(zhí)行舉了很多例子,比如下面這個,為頁面的某一部分不停地更新(以及不斷地執(zhí)行)
(function loop(){ doStuff(); $("#update").load("awesomething.php",function(){ loop(); }) //setTimeout(loop, 100) })()
jQuery 1.11版本的黑箱采用了全新的工廠方法,本文不探究
noConflict的實現(xiàn)這個函數(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; };
我們可以看到防沖突的實現(xiàn)是先把之前的JQuery 和 $ 存起來,noConflict被調(diào)用的時候,再還給它們
與原生js屬性命名的轉(zhuǎn)換1.4版本用的是props對象來存放jquery對屬性操作與原生js屬性操作的對應關系
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 這個對象是存放對應關系表的,比如class轉(zhuǎn)換成className,prop函數(shù)負責處理這個關系表。
而下面的each很有意思,遍歷數(shù)組中那些屬性,然后把他們小寫格式對應到自己,放到 propFix
我們知道在jQuery里一些動畫我們可以直接通過normal,fast,slow 來定義實現(xiàn)速度,這個在源碼里是這樣定義的
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")
一種是可以對default屬性做條件判斷,還有一種自定義速度,比如"veryfast"
.readyready函數(shù) 1.11版本和1.4版本有較大的差距,新版中很多東西我也不太能理解,我們就簡單的把核心拿出來看一下
jQuery.ready.promise = function( obj ) { //...省略若干 } else if ( document.addEventListener ) { // 使用addEventListener "DOMContentLoaded" 監(jiān)聽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去做確保載入完成的工作,重點是
document.addEventListener( "DOMContentLoaded", completed, false );
window.addEventListener( "load", completed, false );
document.attachEvent( "onreadystatechange", completed );
window.attachEvent( "onload", completed );
兼容性考量的四種檢查方式
其中從top開始,做了一件事情就是IE下面,dom節(jié)點判斷是否有scroll,在IE下如果dom有scroll,沒有scroll到的元素對ready會有影響,這里面我的理解不夠,總之jQuery里用到了一個叫做Diego Perini的技巧,可以在注釋里的地址看到更多內(nèi)容。
選擇器$("#id").find("tag.thing") --- faster $("#id tag.thing") ------- using sizzle
原作者在這里說了一個jquery效率的問題,上面的方法更快一些,而下面的方法稍微慢,簡單地說是因為下面的方法調(diào)用了sizzle,通過sizzle其實轉(zhuǎn)換成上述的模式,而id的調(diào)用則是直接過jQuery.init.
這里需要擴展一下,我們來看一下1.11里jQuery對象究竟長啥樣
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對象其實是return了一個它自己的構(gòu)造函數(shù)叫做init,我們再來看一下init做了些什么
// Initialize a jQuery object init = jQuery.fn.init = function( selector, context ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) //超級省略...下略 // 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;
從上面的摘取的代碼注釋中,我們可以看到jq自己的構(gòu)造函數(shù)里處理了哪些情況,其中包括html標簽名和id的獲取,意味著這兩種獲取是最底層的,此外$()的其他處理都要經(jīng)過其他的函數(shù),效率上不如上述處理情況。
同時我們也能看到init的原型被賦予了jQuery.fn, 關于jQuery對象的相關內(nèi)容,感興趣的朋友可以再多去了解一些。
jQ的狀態(tài)選擇符,比如:not,:has,:eq存放在
Sizzle.selectors.pseudos里面
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/78104.html
摘要:目前正在廣泛使用的框架之一就是。是一系列使用編寫的自定義控件,用于創(chuàng)建快速響應式的和可擴展的控件。的組件主要是使用,并提供了交互式,動態(tài)和高度可定制的小部件。例如,演示了如何使用自定義控件,嵌套面板和其它元素。 在建立Web應用時,通常都需要用到一些有用的UI組件。無論應用中需要的是日歷,滑塊,圖形或其它用于提升或簡化用戶交互的組件,那么都面臨兩種選擇:要么自己來創(chuàng)建這些組件,要么使用...
摘要:計算數(shù)組的極值微信面試題獲取元素的最終前端掘金一題目用代碼求出頁面上一個元素的最終的,不考慮瀏覽器,不考慮元素情況。 Excuse me?這個前端面試在搞事! - 前端 - 掘金金三銀四搞事季,前端這個近年的熱門領域,搞事氣氛特別強烈,我朋友小偉最近就在瘋狂面試,遇到了許多有趣的面試官,有趣的面試題,我來幫這個搞事 boy 轉(zhuǎn)述一下。 以下是我一個朋友的故事,真的不是我。 ... ja...
摘要:能不能支持數(shù)據(jù)丟失啊可以的,參考我們之前說的那個數(shù)據(jù)零丟失方案其實一個肯定是很復雜的,其實這是個開放題,就是看看你有沒有從架構(gòu)角度整體構(gòu)思和設計的思維以及能力。其實回答這類問題,說白了,起碼不求你看過那技術的源碼,起碼你大概知道那個技術的基本原理,核心組成部分,基本架構(gòu)構(gòu)成,然后參照一些開源的技術把一個系統(tǒng)設計出來的思路說一下就好 比如說這個消息隊列系統(tǒng),我們來從以下幾個角度來考慮一下 (1...
摘要:這個是類似的一種結(jié)構(gòu),這個一般就是可以將結(jié)構(gòu)化的數(shù)據(jù),比如一個對象前提是這個對象沒嵌套其他的對象給緩存在里,然后每次讀寫緩存的時候,可以就操作里的某個字段。 1.string 這是最基本的類型了,就是普通的set和get,做簡單的kv緩存。 2.hash 這個是類似map的一種結(jié)構(gòu),這個一般就是可以將結(jié)構(gòu)化的數(shù)據(jù),比如一個對象(前提是這個對象沒嵌套其他的對象)給緩存在redis里,然后每次...
閱讀 634·2021-09-22 10:02
閱讀 6324·2021-09-03 10:49
閱讀 565·2021-09-02 09:47
閱讀 2151·2019-08-30 15:53
閱讀 2929·2019-08-30 15:44
閱讀 900·2019-08-30 13:20
閱讀 1812·2019-08-29 16:32
閱讀 889·2019-08-29 12:46