jQuery 3.0的domManip淺析

来源:http://www.cnblogs.com/snandy/archive/2016/09/03/5836155.html
-Advertisement-
Play Games

domManip 這個函數的歷史由來已久,從 jQuery 1.0 版本開始便存在了,一直到最新的 jQuery 版本。可謂是元老級工具函數。 domManip 的主要功能是為了實現 DOM 的插入和替換。具體共為以下 5 個函數服務 內部後插入(append) 內部前插入(prepend) 外部前 ...


domManip 這個函數的歷史由來已久,從 jQuery 1.0 版本開始便存在了,一直到最新的 jQuery 版本。可謂是元老級工具函數。

 

domManip 的主要功能是為了實現 DOM 的插入和替換。具體共為以下 5 個函數服務

  • 內部後插入(append)
  • 內部前插入(prepend)
  • 外部前插入(before)
  • 外部後插入(after)
  • 替換元素 (replaceWith,1.9.x 之前的版本沒有使用 domMainp)

 

而一個 each 就生成了另外 5 個函數:appendTo、prependTo、insertBefore、insertAfter、replaceAll

jQuery.each( {
	appendTo: "append",
	prependTo: "prepend",
	insertBefore: "before",
	insertAfter: "after",
	replaceAll: "replaceWith"
}, function( name, original ) {
	jQuery.fn[ name ] = function( selector ) {
		var elems,
			ret = [],
			insert = jQuery( selector ),
			last = insert.length - 1,
			i = 0;

		for ( ; i <= last; i++ ) {
			elems = i === last ? this : this.clone( true );
			jQuery( insert[ i ] )[ original ]( elems );

			// Support: Android <=4.0 only, PhantomJS 1 only
			// .get() because push.apply(_, arraylike) throws on ancient WebKit
			push.apply( ret, elems.get() );
		}

		return this.pushStack( ret );
	};
} );

 

如圖

 

內部調用如圖

 

源碼

append: function() {
	return domManip( this, arguments, function( elem ) {
		if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
			var target = manipulationTarget( this, elem );
			target.appendChild( elem );
		}
	} );
},
prepend: function() {
	return domManip( this, arguments, function( elem ) {
		if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
			var target = manipulationTarget( this, elem );
			target.insertBefore( elem, target.firstChild );
		}
	} );
},
before: function() {
	return domManip( this, arguments, function( elem ) {
		if ( this.parentNode ) {
			this.parentNode.insertBefore( elem, this );
		}
	} );
},
after: function() {
	return domManip( this, arguments, function( elem ) {
		if ( this.parentNode ) {
			this.parentNode.insertBefore( elem, this.nextSibling );
		}
	} );
},
replaceWith: function() {
	var ignored = [];

	// Make the changes, replacing each non-ignored context element with the new content
	return domManip( this, arguments, function( elem ) {
		var parent = this.parentNode;

		if ( jQuery.inArray( this, ignored ) < 0 ) {
			jQuery.cleanData( getAll( this ) );
			if ( parent ) {
				parent.replaceChild( elem, this );
			}
		}

	// Force callback invocation
	}, ignored );
}

  

domManip 的實現

domManip 的主要功能就是添加 DOM 元素,因為添加的位置不同而提供了四個公開函數 append、prepend、before、after,此外還有一個 replaceWith。簡單說 domManip 就做了兩件事

  1. 先完成 DOM 節點添加
  2. 如果添加的 DOM 節點內有 script 標簽,需要額外處理下。對於可執行的 script (通過type屬性判斷)則執行其內的腳本代碼,其它的則不執行。

 

domManip 依賴的一個重要函數就是 buildFragment,為 DOM 插入提高了性能。

 

domManip 內對 script 節點元素做了特殊處理

  1. script 無 type 屬性,預設會執行其內的 JS 腳本
  2. script 的 type="text/javascript" 或 type="text/ecmascript" ,會執行其內的 JS 腳本
  3. script 如果有 src 屬性,會執行 $._evalUrl 請求遠程的 JS 文件並執行
  4. 其它不會執行 JS 腳本,有時我們會用 script 來做 html 模板,如 underscore.js,type="text/template" 或 type="text/plain" 這種,其內的 JS 都不會被執行

此外 dataPriv.access( node, "globalEval" ),這一句標示瞭如果該 script 已經執行過,則不會再次執行。或者說執行後會設置一個 globalEval: true 的標示。


domManip 內部依賴 buildFragment、restoreScript、disableScript、jQuery._evalUrl、DOMEval 這幾個小函數,而 restoreScript、jQuery._evalUrl 也僅在 domManip 用到。

// Replace/restore the type attribute of script elements for safe DOM manipulation
function disableScript( elem ) {
	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
	return elem;
}
function restoreScript( elem ) {
	var match = rscriptTypeMasked.exec( elem.type );

	if ( match ) {
		elem.type = match[ 1 ];
	} else {
		elem.removeAttribute( "type" );
	}

	return elem;
}
jQuery._evalUrl = function( url ) {
	return jQuery.ajax( {
		url: url,

		// Make this explicit, since user can override this through ajaxSetup (#11264)
		type: "GET",
		dataType: "script",
		cache: true,
		async: false,
		global: false,
		"throws": true
	} );
};

  

domManip 經歷了各個版本的演變

  1. 3.0.x 之前版本的 domManip 函數是掛在 jQuery 對象上面的(jQuery.fn.domManip),即通過 $().domManip 方式可以訪問;3.0.x 後 domManip 是一個私有函數,外部無法訪問
  2. 1.2.x 之前 domManip 有 4 個參數;1.3.x ~ 1.9.x 是 3 個參數;2.x 只有 2 個參數;3.x 有 4 個參數
  3. 1.9.x 之前的版本 replaceWith 沒有使用 domMainp

 

相關:

http://www.cnblogs.com/snandy/p/5760742.html


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

-Advertisement-
Play Games
更多相關文章
  • 通過繼承ActionSupport類來完成Action開發,ActionSupport類不僅對Action介面進行簡單實現, 同時增加了驗證、本地化等支持 。真實開發中自定義Action都需要繼承該類。對用戶登錄添加表單驗證功能 ActionSupport類的作用: struts2不要求我們自己設計 ...
  • 任務隊列是指能夠實現任務在多線程間安全傳遞的先入先出的隊列。 任務是指組合了數據和操作的對象,這裡面定義為CTask類的對象。 任務的實現: Task.cpp 1 #include "stdafx.h" 2 #include "Task.h" 3 #include <iostream> 4 usin ...
  • 一、MD5加密 直接乾,這裡以一個登錄頁面為例: 主要就是記得比對的時候也使用MD5,所以存在資料庫中的時候就是密碼保存的了 二、Crypt加密演算法 同樣是一個單向加密演算法,無法由密文直接得到明文密碼(和MD5一樣); 語法:string crypt(string $str[,string $sal ...
  • 為何一說程式員就是吃青春飯,各行各業按理不應該是呆的越久懂得經驗越多嗎? 為何時間帶來的不是成就感,而是恐慌感,還有轉型的困惑? 那幾年的項目經驗到底為程式員提供了什麼? 為何程式員開發項目幾年之後仍然成為不了架構師,僅僅是項目少的問題嗎? 從項目經驗到底得到了什麼? 有一種程式員一直做底層開發,以 ...
  • 回到目錄 Lind.DDD.Utils.HttpHelper組件主要實現了對HTTP的各種操作,如Get,Post,Put和Delete,它屬於最純粹的操作,大叔把它封裝的目的主要為了實現與API安全授權的統一,你不可能為每個請求都寫一個“邏輯完全一樣的加密規則”,這是違背DRY原則的,我們應該通過 ...
  • 最近幾年在做項目過程中發現項目中出現的問題,一部分由於項目前期一些很基礎的技術系統沒有註意, 所以總結了項目開始搭建架構的時候應該註意的技術問題和技術框架的選型。 所有所謂的最佳實踐只是參考,本文也不例外。 異常處理是程式最基本的問題,我見過最多的處理異常的方式,在業務層一個大的try catch) ...
  • 如何使用CSS來製作圖形,比如說圓形,半圓形,三角形等。今天我特意在網上查閱了一下,介紹這樣的教程還是蠻多的,因此我也決定整理一份相關教程出來與大家一起分享。 很少會有人意識到,當瀏覽器繪製的border,會有一個角度的問題。我們就是得用這樣的一個技巧來製作三角的效果。我們只需要保證一邊的邊框是有... ...
  • × 目錄 [1]寫法 [2]增強 [3]實現 前面的話 本文先詳細介紹回到頂部的5種寫法,然後對其實現功能增加,最後得到最終實現 寫法 【1】錨點 使用錨點鏈接是一種簡單的返回頂部的功能實現。該實現主要在頁面頂部放置一個指定名稱的錨點鏈接,然後在頁面下方放置一個返回到該錨點的鏈接,用戶點擊該鏈接即可 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...