深入理解jQuery3.0的domManip函数


Posted in Javascript onSeptember 01, 2016

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 );
  };
} );

如图

深入理解jQuery3.0的domManip函数

内部调用如图

深入理解jQuery3.0的domManip函数

源码

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

以上所述是小编给大家介绍的jQuery3.0的domManip函数,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
extjs fckeditor集成代码
May 10 Javascript
父子窗体间传递JSON格式的数据的代码
Dec 25 Javascript
JavaScript自定义事件介绍
Aug 29 Javascript
javascript:void(0)是什么意思示例介绍
Nov 17 Javascript
3种js实现string的substring方法
Nov 09 Javascript
js图片轮播手动切换效果
Nov 10 Javascript
javascript实现网页端解压并查看zip文件
Dec 15 Javascript
jQuery实现伪分页的方法分享
Feb 17 Javascript
JavaScript和jQuery获取input框的绝对位置实现方法
Oct 13 Javascript
js实现右键菜单功能
Nov 28 Javascript
js实现加载页面就自动触发超链接的示例
Aug 31 Javascript
element-ui 本地化使用教程详解
Oct 28 Javascript
总结AngularJS开发者最常犯的十个错误
Aug 31 #Javascript
ES6记录异步函数的执行时间详解
Aug 31 #Javascript
基于angularjs实现图片放大镜效果
Aug 31 #Javascript
用AngularJS的指令实现tabs切换效果
Aug 31 #Javascript
简洁实用的BootStrap jQuery手风琴插件
Aug 31 #Javascript
AngularJS实现一次监听多个值发生的变化
Aug 31 #Javascript
利用Angularjs和bootstrap实现购物车功能
Aug 31 #Javascript
You might like
php你的验证码安全码?
2007/01/02 PHP
php中计算程序运行时间的类代码
2012/11/03 PHP
PHP遍历目录函数opendir()、readdir()、closedir()、rewinddir()总结
2014/11/18 PHP
smarty实现多级分类的方法
2014/12/05 PHP
thinkPHP3.x常量整理(预定义常量/路径常量/系统常量)
2016/05/20 PHP
laravel获取不到session的三种解决办法【推荐】
2018/09/16 PHP
laravel-admin解决表单select联动时,编辑默认没选上的问题
2019/09/30 PHP
关于js类的定义
2011/06/28 Javascript
D3.js中data(), enter() 和 exit()的问题详解
2015/08/17 Javascript
Markdown与Bootstrap相结合实现图片自适应属性
2016/05/04 Javascript
JavaScript知识点总结(五)之Javascript中两个等于号(==)和三个等于号(===)的区别
2016/05/31 Javascript
Bootstrap选项卡学习笔记分享
2017/02/13 Javascript
jQuery实现倒计时功能 jQuery实现计时器功能
2017/09/19 jQuery
css和js实现弹出登录居中界面完整代码
2017/11/26 Javascript
Vue-cropper 图片裁剪的基本原理及思路讲解
2018/04/17 Javascript
微信小程序文章详情页面实现代码
2018/09/10 Javascript
利用Bootstrap Multiselect实现下拉框多选功能
2019/04/08 Javascript
JavaScript canvas绘制圆弧与圆形
2020/02/18 Javascript
微信小程序实现下滑到底部自动翻页功能
2020/03/07 Javascript
[01:11:48]Fnatic vs IG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python模块学习 datetime介绍
2012/08/27 Python
Python中动态获取对象的属性和方法的教程
2015/04/09 Python
完美解决python遍历删除字典里值为空的元素报错问题
2016/09/11 Python
深入理解Python爬虫代理池服务
2018/02/28 Python
用django-allauth实现第三方登录的示例代码
2019/06/24 Python
Python获取统计自己的qq群成员信息的方法
2019/11/15 Python
Python标准库json模块和pickle模块使用详解
2020/03/10 Python
win10下python3.8的PIL库安装过程
2020/06/08 Python
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
新郎新娘婚礼答谢词
2014/01/11 职场文书
通信研究生自荐信
2014/02/01 职场文书
经济类毕业生求职信
2014/06/26 职场文书
诚信高考倡议书
2019/06/24 职场文书
修改MySQL的默认密码的四种小方法
2021/05/26 MySQL
SpringBoot集成Druid连接池连接MySQL8.0.11
2021/07/02 Java/Android
Win10本地连接不见了怎么恢复? win10系统电脑本地连接不见了解决方法
2023/01/09 数码科技