深入理解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 相关文章推荐
document.all的一个比较完整的总结及案例
Jan 31 Javascript
js判断游览器类型及版本号的代码
May 11 Javascript
javascript实现禁止复制网页内容汇总
Dec 30 Javascript
JS简单生成两个数字之间随机数的方法
Aug 03 Javascript
前端构建工具之gulp的语法教程
Jun 12 Javascript
Vue单页应用引用单独的样式文件的两种方式
Mar 30 Javascript
Element Input组件分析小结
Oct 11 Javascript
node之本地服务器图片上传的方法示例
Mar 26 Javascript
Vue实现导航栏的显示开关控制
Nov 01 Javascript
使用Vue.set()方法实现响应式修改数组数据步骤
Nov 09 Javascript
在Webpack中用url-loader处理图片和字体的问题
Apr 28 Javascript
js实现金山打字通小游戏
Jul 24 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
PHP4 与 MySQL 数据库操作函数详解
2006/10/09 PHP
PHP 实例化类的一点摘记
2008/03/23 PHP
PHP中设置时区,记录日志文件的实现代码
2013/01/07 PHP
显示程序执行时间php函数代码
2013/08/29 PHP
php实现XSS安全过滤的方法
2015/07/29 PHP
Symfony2学习笔记之模板用法详解
2016/03/17 PHP
php中array_unshift()修改数组key注意事项分析
2016/05/16 PHP
php实现文件预览功能
2017/05/23 PHP
Laravel 已登陆用户再次查看登陆页面的自动跳转设置方法
2019/09/30 PHP
PHPUnit + Laravel单元测试常用技能
2019/11/06 PHP
php 中的信号处理操作实例详解
2020/03/04 PHP
Prototype使用指南之string.js
2007/01/10 Javascript
基于jQuery的自动完成插件
2011/02/03 Javascript
js变量、作用域及内存详解
2014/09/23 Javascript
Jquery 实现table样式的设定
2015/01/28 Javascript
Jquery幻灯片特效代码分享--打开页面随机选择切换方式(3)
2015/08/15 Javascript
JS实现从顶部下拉显示的带动画QQ客服特效代码
2015/10/24 Javascript
Javascript缓存API
2016/06/14 Javascript
静态页面html中跳转传值的JS处理技巧
2016/06/22 Javascript
AngularJS 依赖注入详解和简单实例
2016/07/28 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
javascript函数的节流[throttle]与防抖[debounce]
2017/11/15 Javascript
ES6 Object属性新的写法实例小结
2019/06/25 Javascript
详细教你微信公众号正文页SVG交互开发技巧
2019/07/25 Javascript
[01:38]DOTA2 2015国际邀请赛中国区预选赛 Showopen
2015/06/01 DOTA
配置 Pycharm 默认 Test runner 的图文教程
2018/11/30 Python
Python中时间datetime的处理与转换用法总结
2019/02/18 Python
python有序查找算法 二分法实例解析
2020/02/18 Python
英国翻新电子产品购物网站:Tech Trade
2017/12/25 全球购物
有影响力的品牌之家:Our Social Collective
2019/06/08 全球购物
英国高级健康和美容产品零售商:Life and Looks
2019/08/01 全球购物
美国知名的隐形眼镜电商:Contacts America
2019/11/19 全球购物
政治表现评语
2014/05/04 职场文书
欢送会主持词
2015/07/01 职场文书
总结会主持词
2015/07/02 职场文书
MySQL系列之六 用户与授权
2021/07/02 MySQL