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

jQuery 3.0的domManip浅析的更多相关文章

  1. jQuery 3.0 的 Data 浅析

    jQuery 3.0 在6月9日正式发布了,3.0 也被称为下一代的 jQuery .这个版本从14年10月开始,其中发布过一次beta 版(2016/1/14,)和候选版(2016/05/20).一 ...

  2. 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 li ...

  3. jQuery 2.0.3 源码分析core - 选择器

         声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢!      打开jQuery源码,一眼看去到处都充斥着正则表达式,jQuery框架的基础就是查询了,查询文档元素对象 ...

  4. jQuery 3.0正式发布

    jQuery 基金会刚刚发布了该 JavaScript 框架的 3.0 版本,并且首次抛弃了对老旧的 IE 浏览器的支持.jQuery 3.0 的工作始于 2014 年 10 月,其最初目标是在 2. ...

  5. jQuery 3.0 的变化

    时隔 3 个月,jQuery 团队终于发布了 3.0 Alpha 版本.有两个版本 jQuery compat 3.0 和 jQuery 3.0. jQuery compat 3.0 对应之前的 1. ...

  6. jQuery 2.0发布,不再支持IE6/7/8

    有时发现jQuery库引用的都对,javascript代码写的也没问题,可是jquery就是出现问题,额--我发现换个jquery库就没问题了,长时间不关注jquery的问题而已: 很多人都没有使用最 ...

  7. PJax在jQuery 3.0无法运行问题修复

    PJax在jQuery 3.0无法运行 [现象] 页面报错:Uncaught TypeError: Cannot read property 'push' of undefined [原因] jQue ...

  8. jQuery 2.0.3 源码分析Sizzle引擎解析原理

    jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...

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

    Android 4.0 ICS SystemUI浅析——StatusBar结构分析 分类: Android2012-06-30 14:45 23687人阅读 评论(8) 收藏 举报 androidsi ...

随机推荐

  1. Java 枚举用法详解

    概念 enum 的全称为 enumeration, 是 JDK 1.5 中引入的新特性. 在Java中,被 enum 关键字修饰的类型就是枚举类型.形式如下: enum Color { RED, GR ...

  2. [Java IO]01_File类和RandomAccessFile类

    File类 File类是java.io包中唯一对文件本身进行操作的类.它可以进行创建.删除文件等操作.   File类常用操作 (1)创建文件 可以使用 createNewFille() 创建一个新文 ...

  3. 一步一步开发Game服务器(二)登陆2

    上一篇文章,讲解了简单的登陆情况.接下来我们继续讲解登陆模块. 在正常的游戏服务器情况下.在尚未登录前可以查看服务器大区情况,登陆后也可以查看服务器大区情况,然后选择大区服务器.进行登录操作. 这样的 ...

  4. 从零开始,搭建博客系统MVC5+EF6搭建框架(2),测试添加数据、集成Autofac依赖注入

    一.测试仓储层.业务层是否能实现对数据库表的操作 1.创建IsysUserInfoRepository接口来继承IBaseRepository父接口 namespace Wchl.WMBlog.IRe ...

  5. 获取documents、tmp、app、Library的路径的方法

    phone沙箱模型的有四个文件夹: documents,tmp,app,Library 1.Documents      您应该将所有的应用程序数据文件写入到这个目录下.这个目录用于存储用户数据或其它 ...

  6. 工厂模式 - Factory

    简单工厂模式 SimpleFactory Pattern,将一个具体类的实例化交给一个静态工厂方法来执行. 特点: 增加功能需要修改工厂类,扩展性较差: 参考: 设计模式学习笔记 - 简单工厂模式: ...

  7. 基于CkEditor实现.net在线开发之路(1)

    我以前的公司使用office sharepoint designer为界面设计器,嵌套各种自定义控件,进行各种管理软件,工作流的开发,遇到比较复杂的逻辑,则采用本地写类库,生成DLL上传到服务器,通过 ...

  8. Myeclipse 的hadoop环境搭建

    https://issues.apache.org/jira/secure/attachment/12460491/hadoop-eclipse-plugin-0.20.3-SNAPSHOT.jar ...

  9. JMeter专题系列(七)聚合报告之 90% Line

    JMeter 官网原文: 90% Line - 90% of the samples took no more than this time. The remaining samples at lea ...

  10. Atitit.提升 升级类库框架后的api代码兼容性设计指南

    Atitit.提升 升级类库框架后的api代码兼容性设计指南 1. 增加api直接增加,版本号在注释上面增加1 2. 废弃api,使用主见@dep1 3. 修改api,1 4. 修改依赖import, ...