jQuery3.0的buildFragment

来源:http://www.cnblogs.com/snandy/archive/2016/08/16/5760742.html
-Advertisement-
Play Games

在 jQuery3.0中,buildFragment 是一個私有函數,用來構建一個包含子節點 fragment 對象。這個 fragment 在 DOM1 中就已經有了,所有瀏覽器都支持。當頻繁操作(添加、插入) DOM 時使用該方法可以提高性能,John resig 做過一個測試及一篇博客。 jQ ...


在 jQuery3.0中,buildFragment 是一個私有函數,用來構建一個包含子節點 fragment 對象。這個 fragment 在 DOM1 中就已經有了,所有瀏覽器都支持。當頻繁操作(添加、插入) DOM 時使用該方法可以提高性能,John resig 做過一個測試及一篇博客

 

jQuery3.0 中 buildFragment 只在 domManip 和 jQuery.parseHTML 中使用,domManip 則被 DOM 操作如 append、prepend、before、after 等方法的所依賴。如下圖

 

buildFragment 函數有 5 個參數,源碼如下

function buildFragment( elems, context, scripts, selection, ignored ) {
	var elem, tmp, tag, wrap, contains, j,
		fragment = context.createDocumentFragment(),
		nodes = [],
		i = 0,
		l = elems.length;

	for ( ; i < l; i++ ) {
		elem = elems[ i ];

		if ( elem || elem === 0 ) {

			// Add nodes directly
			if ( jQuery.type( elem ) === "object" ) {

				// Support: Android <=4.0 only, PhantomJS 1 only
				// push.apply(_, arraylike) throws on ancient WebKit
				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );

			// Convert non-html into a text node
			} else if ( !rhtml.test( elem ) ) {
				nodes.push( context.createTextNode( elem ) );

			// Convert html into DOM nodes
			} else {
				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );

				// Deserialize a standard representation
				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
				wrap = wrapMap[ tag ] || wrapMap._default;
				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];

				// Descend through wrappers to the right content
				j = wrap[ 0 ];
				while ( j-- ) {
					tmp = tmp.lastChild;
				}

				// Support: Android <=4.0 only, PhantomJS 1 only
				// push.apply(_, arraylike) throws on ancient WebKit
				jQuery.merge( nodes, tmp.childNodes );

				// Remember the top-level container
				tmp = fragment.firstChild;

				// Ensure the created nodes are orphaned (#12392)
				tmp.textContent = "";
			}
		}
	}

	// Remove wrapper from fragment
	fragment.textContent = "";

	i = 0;
	while ( ( elem = nodes[ i++ ] ) ) {

		// Skip elements already in the context collection (trac-4087)
		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
			if ( ignored ) {
				ignored.push( elem );
			}
			continue;
		}

		contains = jQuery.contains( elem.ownerDocument, elem );

		// Append to fragment
		tmp = getAll( fragment.appendChild( elem ), "script" );

		// Preserve script evaluation history
		if ( contains ) {
			setGlobalEval( tmp );
		}

		// Capture executables
		if ( scripts ) {
			j = 0;
			while ( ( elem = tmp[ j++ ] ) ) {
				if ( rscriptType.test( elem.type || "" ) ) {
					scripts.push( elem );
				}
			}
		}
	}

	return fragment;
}

 

該方法主要執行步驟

  1. 通過第二個參數 content 創建 fragment
  2. 通過第一個參數 elems 構建 nodes ,將 elems 內元素轉成 DOM 元素存放於數組 nodes 中
  3. 將 nodes 里元素迴圈放入添加到文檔碎片 fragment 上
  4. 返回 fragment

 

重點在第 2 步,構建 nodes,有 3 種情形

  1. elem 是 DOM 元素(根據nodeType判斷),直接放入 nodes 數組中
  2. elem 是字元串且不是 HTML tag,創建文本節點對象(textNode),放入 nodes 數組中
  3. elem 是字元串且是 HTML tag,將其轉成 DOM 元素,放入 nodes 數組中

 

如圖示

 

後面的兩個參數需要註意下

1. 最後兩個參數 selection 和 ignored 只在 replaceWith 方法里使用。需要瞭解的是 replaceWith 只做節點替換,不會替換先前元素的所有數據(Data),比如綁定事件,$.data 都不會被新元素擁有。

 

2. scripts 參數只在 jQuery.parseHTML 方法里使用(domManip里傳false),當 jQuery.parseHTML 的第三個參數 keepScripts 為 false 時將刪除節點里所有的 script tag

 

buildFragment 在 jQuery 各個版本中的演變

  1. 1.0.x ~ 1.3.x 中沒有 buildFragment 函數,即沒有抽取出該函數為 domManip 服務
  2. 1.4.x 中首次引入 buildFragment ,當時是掛在 jQuery 上的靜態方法,有三個參數 args, nodes, scripts。一直到2.x.x 依然是公開可以訪問的
  3. 3.x.x 開始 buildFragment 變成了一個私有函數,只能在 jQuery 代碼內部訪問,客戶端程式員無法訪問

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • canvas元素 可被用來通過腳本(通常是JavaScript)繪製圖形。比如,它可以被用來繪製圖形,製作圖片集合,甚至用來實現動畫效果。你可以(也應該)在元素標簽內寫入可提供替代的的代碼內容,這些內…容將會在在舊的、不支持canvas元素的瀏覽器或是禁用了JavaScript的瀏覽器內渲染並展現。 ...
  • 這是一款使用純CSS3製作的單頁切換導航菜單界面設計效果。該頁面效果中,在頁面的左側垂直排放一組導航按鈕,當點擊導航按鈕時,相應的頁面會從屏幕右側滑動出來,效果非常炫酷。 線上預覽 源碼下載 使用方法 該單頁切換導航菜單界面的HTML結構如下: 1 2 3 4 5 6 7 8 9 10 11 12 ...
  • RSA加密演算法是目前最有影響力的公鑰加密演算法,它能夠抵抗到目前為止已知的絕大多數密碼攻擊。 ...
  • CSS常用樣式之自定義動畫(關鍵幀、動畫名稱、動畫時間、動畫過渡速度、動畫延遲時間、動畫執行次數、動畫的順序、動畫的狀態、動畫時間之外的狀態) ...
  • canvas也有css3里transform的變換功能,transform的底層運算的方式是運用了線性代數里矩陣, 而矩陣是在我們的生活實踐中會經常被使用,它可以把複雜的空間問題呈現出來,它還有很多實踐的 地方,然後不懂它的人會覺得很難,如果要鑽研,這方面知識是不能少的。 canvas里封裝好的變換 ...
  • Ajax的伺服器端用PrintWriter out=resp.getWriter()來響應數據的時候,out.print(0)、out.print(1)來表示成功或失敗,而不用out.write是有原因的,首先來看一下print和write兩者的異同點。 共同點是:兩者都不刷新頁面,只在原來的頁面寫 ...
  • 1、對於string,number等基礎類型,==和 是有區別的 1)不同類型間比較,==之比較“轉化成同一類型後的值”看“值”是否相等, 如果類型不同,其結果就是不等 2)同類型比較,直接進行“值”比較,兩者結果一樣 2、對於Array,Object等高級類型,==和 是沒有區別的 進行“指針地址 ...
  • Devrama Slider 是個圖像滑塊,帶有許多非常有趣的特性。 它不僅支持圖像還支持 HTML 內容。 響應式 方便 CSS3 轉換 轉換效果 進度條 高級的預載入和延遲載入 CSS 自定義 用戶可以定義導航或者控制器 線上實例 實例演示 使用方法 複製 複製 下載 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...