jQuery3.0的domManip浅析

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
时间: 2024-12-07 18:50:32

jQuery3.0的domManip浅析的相关文章

jQuery 3.0的domManip浅析

domManip 这个函数的历史由来已久,从 jQuery 1.0 版本开始便存在了,一直到最新的 jQuery 版本.可谓是元老级工具函数. domManip 的主要功能是为了实现 DOM 的插入和替换.具体共为以下 5 个函数服务 内部后插入(append) 内部前插入(prepend) 外部前插入(before) 外部后插入(after) 替换元素 (replaceWith,1.9.x 之前的版本没有使用 domMainp) 而一个 each 就生成了另外 5 个函数:appendTo.p

jQuery 3.0 的 Data 浅析

jQuery 3.0 在6月9日正式发布了,3.0 也被称为下一代的 jQuery .这个版本从14年10月开始,其中发布过一次beta 版(2016/1/14,)和候选版(2016/05/20).一路走来,颇为不易. 文章目录 Data浅析 Data在jQuery内部的使用 1.x.x 和 2.x.x 的比较 一.Data浅析 jQuery 3.0 中的 Data 是内部使用的,定义为一个“类”.一共用它创建了两个对象,dataPriv 和 dataUser.Data 有 1 个对象属性(ex

jQuery3.0的buildFragment

在 jQuery3.0中,buildFragment 是一个私有函数,用来构建一个包含子节点 fragment 对象.这个 fragment 在 DOM1 中就已经有了,所有浏览器都支持.当频繁操作(添加.插入) DOM 时使用该方法可以提高性能,John resig 做过一个测试及一篇博客. jQuery3.0 中 buildFragment 只在 domManip 和 jQuery.parseHTML 中使用,domManip 则被 DOM 操作如 append.prepend.before

Android 4.0 ICS SystemUI浅析——StatusBar结构分析

Android 4.0 ICS SystemUI浅析——StatusBar结构分析 分类: Android2012-06-30 14:45 23687人阅读 评论(8) 收藏 举报 androidsignal代码分析iconseclipse平台 在上一篇文章<Android 4.0 ICS SystemUI浅析——SystemUI启动流程>中以及提到了SystemUI的组成,本文主要分析其中的StatusBar结构. 1.布局概览 首先,我们通过hierarchyviewer这个工具来查看一下

Apache Spark-1.0.0源码浅析(三 ):作业提交

RDD的操作可以分为Transformations和Actions,Transformations是lazy的不立即执行,Action则会触发作业的提交和执行.例如本例中的foreach def foreach(f: T => Unit) { sc.runJob(this, (iter: Iterator[T]) => iter.foreach(f)) } 一句话,Actions调用sc.runJob触发作业运行. SparkContext中的runJob有多个版本的重载 foreach调用的

Android5.0通知变化浅析-最近在Android5.1设备上发现一个问题:通知图标变成了白色的

目前在Android中通知的使用还是很常见的,为了做版本兼容,常用兼容包NotificationCompat.Builder和 Notification.Builder. NotificationCompat.Builder位于v4扩展包内(version 4 Support Library) Notification.Builder在Android 3.0 开始引入(API level 11). 最近在Android5.0设备上发现一个问题:通知图标突然变成了白色的方块而不是代码中设置的ico

Apache Spark-1.0.0源码浅析(一):引子

Apache Spark版本迭代速度很快,但是基本框架和经典组件保持这统一模式,所以学习Spark源码,我选择的是Apache Spark-1.0.0版本,通过分析几个主要模块的工作原理,理解Spark的运行过程. 通过LocalWordCount程序,调试Spark源码: LocalWordCount首先通过SparkConf设置Master和AppName,然后以SparkConf为参数实例化SparkContext,通过SparkContext读取本地文件,分割文本计算单词数量,最后打印结

jQuery 3.0 的 Data

jQuery 3.0 的 Data Snandy If you cannot hear the sound of the genuine in you, you will all of your life spend your days on the ends of strings that somebody else pulls. jQuery 3.0 的 Data 浅析 jQuery 3.0 在6月9日正式发布了,3.0 也被称为下一代的 jQuery .这个版本从14年10月开始,其中发布

Jqury元素.get(0)转换为JavaScript元素 -时间倒计时

html+css布局: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title> 倒计时2</title> <style> /* reset css 样式重置 */ body,p,pre,h1,h2,h3,h4,h5,h6,ul,ol,li,dl,dt,dd,table,tr,td,div,img,f