深入理解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 相关文章推荐
JS 页面自动加载函数(兼容多浏览器)
May 18 Javascript
一个支持任意尺寸的图片上下左右滑动效果
Aug 24 Javascript
Angular用来控制元素的展示与否的原生指令介绍
Jan 07 Javascript
简介JavaScript中的push()方法的使用
Jun 09 Javascript
jQuery实现径向动画菜单效果
Jul 17 Javascript
AngularJS教程之简单应用程序示例
Aug 16 Javascript
Bootstrap如何创建表单
Oct 21 Javascript
150行代码带你实现微信小程序中的数据侦听
May 17 Javascript
Vue CLI3中使用compass normalize的方法
May 30 Javascript
webpack优化之代码分割与公共代码提取详解
Nov 22 Javascript
使用Vue Composition API写出清晰、可扩展的表单实现
Jun 10 Javascript
javascript+css实现俄罗斯方块小游戏
Jun 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
php5 mysql分页实例代码
2008/04/10 PHP
php的chr和ord函数实现字符加减乘除运算实现代码
2011/12/05 PHP
个人写的PHP验证码生成类分享
2014/08/21 PHP
PHP实现权限管理功能示例
2017/09/22 PHP
Google Suggest ;-) 基于js的动态下拉菜单
2006/10/11 Javascript
一个cssQuery对象 javascript脚本实现代码
2009/07/21 Javascript
IE不支持getElementsByClassName最终完美解决方案
2012/12/17 Javascript
js onload处理html页面加载之后的事件
2013/10/30 Javascript
JavaScript两种跨域技术全面介绍
2014/04/16 Javascript
JavaScript中的alert()函数使用技巧详解
2014/12/29 Javascript
JQuery实现Ajax加载图片的方法
2015/12/24 Javascript
基于JavaScript实现轮播图原理及示例
2020/04/10 Javascript
浅谈Express异步进化史
2017/09/09 Javascript
微信小程序url与token设置详解
2017/09/26 Javascript
vue 录制视频并压缩视频文件的方法
2018/07/27 Javascript
如何在 JavaScript 中更好地利用数组
2018/09/27 Javascript
vue+node实现图片上传及预览的示例方法
2018/11/22 Javascript
vue input实现点击按钮文字增删功能示例
2019/01/29 Javascript
react koa rematch 如何打造一套服务端渲染架子
2019/06/26 Javascript
解决三元运算符 报错“SyntaxError: can''t assign to conditional expression”
2020/02/12 Javascript
JS中准确判断变量类型的方法
2020/06/01 Javascript
vue mvvm数据响应实现
2020/11/11 Javascript
python创造虚拟环境方法总结
2019/03/04 Python
python打印直角三角形与等腰三角形实例代码
2019/10/20 Python
Python+OpenCV实现实时眼动追踪的示例代码
2019/11/11 Python
关于Python 中的时间处理包datetime和arrow的方法详解
2020/03/19 Python
全面解析CSS Media媒体查询使用操作(推荐)
2017/08/15 HTML / CSS
欧舒丹比利时官网:L’OCCITANE比利时
2017/04/25 全球购物
美国鲍勃商店:Bob’s Stores
2018/07/22 全球购物
Senreve官网:美国旧金山的奢侈手袋品牌
2019/03/21 全球购物
怎样从/向数据文件读/写结构
2014/11/23 面试题
汽车维修求职信
2014/06/15 职场文书
好员工观后感
2015/06/17 职场文书
浅谈redis整数集为什么不能降级
2021/07/25 Redis
SQL Server中常用截取字符串函数介绍
2022/03/16 SQL Server
mysql查询结果实现多列拼接查询
2022/04/03 MySQL