學習源碼第五天(難得可貴)
阿新 • • 發佈:2019-04-25
pan directly 源碼 查找 ini length quick nbsp init
else { elem = document.getElementById(match[2]); // 以id的形式獲取元素 // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if (elem && elem.parentNode) { // Inject the element directly into the jQuery objectthis.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; }
這裏處理的是rquickExpr另一種情況‘#aa‘的形式,首先用原生方法通過match[2](‘#dd’這種的字符串)獲取元素,然後如果元素存在就把this的length改為1,‘0’項就是獲取到的元素節點,context的作用域因為是id的形式所以是document,selecor作為值添加到this.selector屬性中,操作完成返回this
說一下elem && elem.parentNode為什麽要多此一舉elem.parentNode,因為在Blackberry 4.6中克隆的節點雖然沒有在DOM樹中,但是可以通過id找到,所以真正在DOM樹中的是有parentNode父節點的,不得不說考慮的真周到
// HANDLE: $(expr, $(...)) ,只要else if (!context || context.jquery) { //如果像$(expr, $(...)) 或者 $(expr) ,轉變成$(document) return (context || rootjQuery).find(selector);//有第二個參數就返回第二個參數的jQuery對象,沒有就返回$(doument),然後去調用find(),總之是$對象去掉用find()
返回一個$節點對象 // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { //處理$(expr, context)[也就是$(‘li‘,document)],也轉變成$(document) return this.constructor(context).find(selector); }
總之一定要變成用$對象去調用find(),把查找作用域都變成$(document),總之內部都是$(document).find(selector),這也解釋了其實我們寫$(‘li‘)這種內部做了一個$(document).find(‘li‘),
其實就是在當前DOM中去查li,當然這還沒涉及到復雜選擇器的情況
this.constructor(context).find(selector);這句話十分巧妙,this.constructor是一個jQuery構造函數,回顧一下:
jQuery = function(selector, context) { // The jQuery object is actually just the init constructor ‘enhanced‘ return new jQuery.fn.init(selector, context, rootjQuery); },
那麽根據第一個參數是context,可知返回了一個init的實例(因為後文把$的原型給了$原型中的init的原型,所以相當於是一個$實例對象 )
//$(節點)
else if (selector.nodeType) { this.context = this[0] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready }
處理$()括號裏面是節點對象$(li),this變為length屬性為1,‘0‘項屬性為DOM節點,context作用域也為DOM節點,這種情況不涉及到查找域,而用selector.nodeType判斷表明了selector是一個DOM節點
學習源碼第五天(難得可貴)