摘要:函數源碼下面是和的源碼,看了之后肯定有話要說函數回調函數好吧,我承認,又是同樣的套路,先交給函數來處理,然后函數,我猜這個時候函數肯定是采用方式使綁定當前。
歡迎來我的專欄查看系列文章。
上一章談到了 dom 的幾個插入操作,雖然插入的方式多種多樣,但只要在懂了原生方法等基礎上,代碼看起來都不是很復雜。比較有意思的一個函數就是 buildFragment 方法,用來將 html 字符串轉換成 dom 碎片。本章來看一下 dom 的其它方法。
說到 elem 的操作,就必然要提一下 elem 的類型。NodeType,一個節點的 nodeType 為 1 表示元素節點,為 3 表示 text 文字節點,為 9 表示 document,11 表示 documentFragment,就是上一章所說的文檔碎片。大概知道這幾個就可以了。
原生的 elem 方法包括 innerHTML,outerHTML,innerText,outerText,然而,在開始本章之前,一定要對這幾個方法很常熟練才行。解密jQuery內核 DOM操作方法(二)html,text,val。
innerHTML 和 outerHTML 一個顯著的差異性就是 outer 會把當前 elem 也一起算進去并獲得 html 字符串,inner 不會。
innerText 和 outerText 獲取時候沒有顯著差異,但是 set 情況下(設置)的時候,outer 會把當前 elem 也給刪掉,使用還是要謹慎。
有時候因為瀏覽器的兼容問題,可以用 textContent 替代 innerText。
access 函數源碼下面是jQuery.fn.html 和 text 的源碼,看了之后肯定有話要說:
jQuery.fn.extends( { html: function( value ) { return access( this, function( value ) { ... // callback 函數 }, null, value, arguments.length ) }), text: function( value ) { return access( this, function( value ) { ...// 回調函數 }, null, value, arguments.length) }) } );
好吧,我承認,又是同樣的套路,先交給 access 函數來處理,然后 callback 函數,我猜這個時候 callback 函數肯定是采用 call 方式使 this 綁定當前 elem。這個套路似曾相識,對,就是 domManip 函數。
其實 access 前面已經介紹了過了,不過還是值得來重現介紹一下。
像 html、text、css 這些函數的功能,都有一個特點,就是可以帶參數,也可以不帶參數,先用 access 函數對參數校正,執行回調。
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, len = elems.length, bulk = key == null; // key values 多種情況 if ( jQuery.type( key ) === "object" ) { chainable = true; for ( i in key ) { access( elems, fn, i, key[ i ], true, emptyGet, raw ); } // Sets 情況 } else if ( value !== undefined ) { chainable = true; // value 為函數,不知道這是一種什么情況 if ( !jQuery.isFunction( value ) ) { raw = true; } if ( bulk ) { // 執行回調 if ( raw ) { fn.call( elems, value ); fn = null; // ...except when executing function values } else { bulk = fn; fn = function( elem, key, value ) { return bulk.call( jQuery( elem ), value ); }; } } // css 走這一步 if ( fn ) { for ( ; i < len; i++ ) { fn( elems[ i ], key, raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) ); } } } // chainable 表示參數長度 0 或 1 if ( chainable ) { return elems; } // Gets if ( bulk ) { return fn.call( elems ); } return len ? fn( elems[ 0 ], key ) : emptyGet; };
access 中出現了一種 value 為函數的情況,沒有碰到過,暫不知道什么意思。access 函數基本沒有做太大的變化處理看,看起來也不是很難。(哈哈,找到了,后面 css 操作的時候,key 可以為 object)
fn.html 源碼現在就是主要來看這個回調函數了,當前的 this 使指向 jQuery 對象的,并沒有指向多帶帶的 elem 元素,html 肯定要進行判斷:
jQuery.fn.extends( { html: function( value ) { return access( this, function( value ) { var elem = this[ 0 ] || {}, i = 0, l = this.length; // 參數為空的情況,get if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; } // set 操作 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { value = jQuery.htmlPrefilter( value ); try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { // cleanData 是清除 dom 綁定 cache 的數據 jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); } } );fn.text 源碼
下面是 text 源碼,關于 html 和 text 在開頭已經介紹了,算是比較基礎的 dom 操作吧,直接來看源碼吧:
jQuery.fn.extends( { text: function( value ) { return access( this, function( value ) { // 前面已經說了,回調函數里的 this 指向 jQuery 對象 return value === undefined ? // get jQuery.text( this ) : // set this.empty().each( function() { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.textContent = value; } } ); }, null, value, arguments.length ); } } );
先來看看 set 的情況,這里有個 empty 函數,源碼在下面,兩個功能,先清空 dom 內容,在刪除 data cache 中保存的數據。這里沒有用 innerText 方法,而是使用 textContent 方法,貌似就 set 來說,textContent 兼容性更好。
jQuery.fn.extends( { empty: function() { var elem, i = 0; for ( ; ( elem = this[ i ] ) != null; i++ ) { if ( elem.nodeType === 1 ) { // Prevent memory leaks jQuery.cleanData( getAll( elem, false ) ); // 清空 elem.textContent = ""; } } return this; }, } );
set 的方法知道了,那么 get 呢?get 首先調用了 jQuery.text 方法,找了半天才找到它在哪里,原來調用的是 Sizzle 中的方法:
jQuery.text = Sizzle.getText; var getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { // elem 是一個 dom 數組 while ( (node = elem[i++]) ) { // 分步來搞 ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // innerText usage removed for consistency of new lines (jQuery #11153) // 依然使用 textContent 方法 if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } // 3 (text)或 4 (4 貌似被移除)直接返回 nodeValue } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } return ret; };總結
我自己在瀏覽器上面測試,發現 textContent 方法并不會把空白符給刪了,而且 jQuery 的 text 方法也沒有做過濾,每個瀏覽器的解析也不一樣,就可能導致瀏覽器帶來的差異,實際使用的時候,還是要小心點好,多長個心眼。
參考Node.NodeType
解密jQuery內核 DOM操作方法(二)html,text,val
本文在 github 上的源碼地址,歡迎來 star。
歡迎來我的博客交流。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86829.html
摘要:瀏覽器緩存簡單介紹下面來簡單介紹一下瀏覽器緩存,以及為何我要在標題中強調該去則去,該留則留。但后來我還是反轉了自己,這種方法雖然能留下瀏覽器緩存,卻做不到該去則去。 本文首發于Array_Huang的技術博客——實用至上,非經作者同意,請勿轉載。原文地址:https://segmentfault.com/a/1190000010317802如果您對本系列文章感興趣,歡迎關注訂閱這里:h...
摘要:瀏覽器緩存簡單介紹下面來簡單介紹一下瀏覽器緩存,以及為何我要在標題中強調該去則去,該留則留。但后來我還是反轉了自己,這種方法雖然能留下瀏覽器緩存,卻做不到該去則去。 本文首發于Array_Huang的技術博客——實用至上,非經作者同意,請勿轉載。原文地址:https://segmentfault.com/a/1190000010317802如果您對本系列文章感興趣,歡迎關注訂閱這里:h...
摘要:歡迎來我的專欄查看系列文章。主要來看函數函數返回值有兩個,其中就是發送函數了,一步一步,發送下來,無需多說明。參考源碼分析系列整體結構源碼分析系列總結觸碰異步詳解本文在上的源碼地址,歡迎來。 歡迎來我的專欄查看系列文章。 關于 ajax,東西太多了,我本來想避開 ajax,避而不提,但覺得 ajax 這么多內容,不說又少點什么,就簡單點來介紹吧,加上最近準備內推面試的時候,看了不少 a...
摘要:歡迎來我的專欄查看系列文章。算是中一個非常可以借鑒的用法,以前聽到這個概念是非常恐懼的,當看了源碼,弄懂原理之后,發現超級有意思。參考源碼分析鉤子機制屬性操作源碼學習本文在上的源碼地址,歡迎來。 歡迎來我的專欄查看系列文章。 hooks 在英語中的意思表示鉤子或掛鉤,在 jQuery 中也有 hooks 這么一個概念,它的功能在考慮到一些兼容性和其它特殊情況的條件下,優先考慮這些特殊情...
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
閱讀 3273·2021-09-30 09:47
閱讀 2290·2021-09-10 10:51
閱讀 1889·2021-09-08 09:36
閱讀 2926·2019-08-30 12:56
閱讀 3027·2019-08-30 11:16
閱讀 2622·2019-08-29 16:40
閱讀 2993·2019-08-29 15:25
閱讀 1631·2019-08-29 11:02