深入理解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 相关文章推荐
javascript检测对象中是否存在某个属性判断方法小结
May 19 Javascript
js转义字符介绍
Nov 05 Javascript
showModelDialog弹出文件下载窗口的使用示例
Nov 19 Javascript
Javascript实现div层渐隐效果的方法
May 30 Javascript
基于HTML+CSS,jQuery编写的简易计算器后续(添加了键盘监听)
Jan 05 Javascript
百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
Feb 19 Javascript
JS递归遍历对象获得Value值方法技巧
Jun 14 Javascript
JavaScript字符串对象
Jan 14 Javascript
jQuery EasyUI 组件加上“清除”功能实例详解
Apr 11 jQuery
微信小程序调用PHP后台接口 解析纯html文本
Jun 13 Javascript
Async Validator 异步验证使用说明
Jul 03 Javascript
使用node打造自己的命令行工具方法教程
Mar 26 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/03/18 PHP
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
Codeigniter生成Excel文档的简单方法
2014/06/12 PHP
在WordPress中使用wp_count_posts函数来统计文章数量
2016/01/05 PHP
php生出随机字符串
2017/07/06 PHP
详解PHP实现支付宝小程序用户授权的工具类
2018/12/25 PHP
php使用filter_var函数判断邮箱,url,ip格式示例
2019/07/06 PHP
JavaScript confirm选择判断
2008/10/18 Javascript
鼠标滑上去后图片放大浮出效果的js代码
2011/05/28 Javascript
为JavaScript类型增加方法的实现代码(增加功能)
2011/12/29 Javascript
那些年,我还在学习jquery 学习笔记
2012/03/05 Javascript
jQuery对象和Javascript对象之间转换的实例代码
2013/03/20 Javascript
详解javascript遍历方式
2015/11/11 Javascript
基于JavaScript实现手机短信按钮倒计时(超简单)
2015/12/30 Javascript
jquery淡入淡出效果简单实例
2016/01/14 Javascript
初探nodeJS
2017/01/24 NodeJs
Vue 报错TypeError: this.$set is not a function 的解决方法
2018/12/17 Javascript
Jquery遍历筛选数组的几种方法和遍历解析json对象,Map()方法详解以及数组中查询某值是否存在
2019/01/18 jQuery
JS实现二维数组元素的排列组合运算简单示例
2019/01/28 Javascript
基于Vue 撸一个指令实现拖拽功能
2019/10/09 Javascript
基于vue+echarts数据可视化大屏展示的实现
2020/12/25 Vue.js
Python中使用装饰器时需要注意的一些问题
2015/05/11 Python
rabbitmq(中间消息代理)在python中的使用详解
2017/12/14 Python
python3判断url链接是否为404的方法
2018/08/10 Python
如何利用python之wxpy模块玩转微信
2020/08/17 Python
Django中日期时间型字段进行年月日时分秒分组统计
2020/11/27 Python
利用CSS3实现平移动画效果示例代码
2016/10/12 HTML / CSS
Pottery Barn阿联酋:购买家具、家居装饰及更多
2019/12/08 全球购物
南京某软件公司的.net面试题
2015/11/30 面试题
入党积极分子思想汇报范文
2014/01/05 职场文书
小学美术教学反思
2014/02/01 职场文书
乡镇精神文明建设汇报材料
2014/08/15 职场文书
员工教育培训协议书
2014/09/27 职场文书
离职证明范本
2015/06/12 职场文书
《云雀的心愿》教学反思
2016/02/23 职场文书
Python中os模块的简单使用及重命名操作
2021/04/17 Python