深入理解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 Select操作大集合
May 26 Javascript
js实现从右向左缓缓浮出网页浮动层广告的方法
May 09 Javascript
详解AngularJS的通信机制
Jun 18 Javascript
javascript鼠标右键菜单自定义效果
Dec 08 Javascript
基于JavaScript实现 网页切出 网站title变化代码
Apr 03 Javascript
JavaScript实现实时更新系统时间的实例代码
Apr 04 Javascript
angular.js中解决跨域问题的三种方式
Jul 12 Javascript
利用angular、react和vue实现相同的面试题组件
Feb 19 Javascript
Vue Promise的axios请求封装详解
Aug 13 Javascript
JS实现可针对算术表达式求值的计算器功能示例
Sep 04 Javascript
微信小程序自定义单项选择器样式
Jul 25 Javascript
JavaScript经典案例之简易计算器
Aug 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
让你成为更出色的PHP开发者的10个技巧
2011/02/25 PHP
PHP 小心urldecode引发的SQL注入漏洞
2011/10/27 PHP
PHP中strtotime函数使用方法分享
2012/01/10 PHP
PDO预处理语句PDOStatement对象使用总结
2014/11/20 PHP
微信自定义菜单的处理开发示例
2015/04/16 PHP
thinkphp3.2.3版本的数据库增删改查实现代码
2016/09/22 PHP
收藏Javascript中常用的55个经典技巧
2007/08/12 Javascript
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
THREE.JS入门教程(4)创建粒子系统
2013/01/24 Javascript
JQuery中对Select的option项的添加、删除、取值
2013/08/25 Javascript
jquery获取tagName再进行判断
2014/05/29 Javascript
javascript判断移动端访问设备并解析对应CSS的方法
2015/02/05 Javascript
使用Chrome浏览器调试AngularJS应用的方法
2015/06/18 Javascript
jQuery实现点击小图片淡入淡出显示大图片特效
2015/09/09 Javascript
Jquery ui datepicker设置日期范围,如只能隔3天【实现代码】
2016/05/04 Javascript
bootstrap的常用组件和栅格式布局详解
2017/05/02 Javascript
JavaScript严格模式下关于this的几种指向详解
2017/07/12 Javascript
小程序分享模块超级详解(推荐)
2019/04/10 Javascript
详解Vue3.0 + TypeScript + Vite初体验
2021/02/22 Vue.js
[04:28]2014DOTA2国际邀请赛 采访小兔子LGD挺进钥匙体育馆
2014/07/14 DOTA
Python中几种操作字符串的方法的介绍
2015/04/09 Python
Python中使用platform模块获取系统信息的用法教程
2016/07/08 Python
对Python3中的input函数详解
2018/04/22 Python
Python Django实现layui风格+django分页功能的例子
2019/08/29 Python
python 爬取腾讯视频评论的实现步骤
2021/02/18 Python
Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用?
2015/08/04 面试题
个人自我评价和职业目标
2014/01/24 职场文书
一体化教学实施方案
2014/05/10 职场文书
岗位标兵事迹材料
2014/05/17 职场文书
大学生志愿者活动总结
2014/06/27 职场文书
乡镇领导干部个人对照检查材料思想汇报
2014/09/23 职场文书
2014年反洗钱工作总结
2014/11/22 职场文书
大学生读书笔记范文
2015/07/01 职场文书
Python连接Postgres/Mysql/Mongo数据库基本操作大全
2021/06/29 Python
DE1103使用报告
2022/04/05 无线电
Win10玩csgo闪退如何解决?Win10玩csgo闪退的解决方法
2022/07/23 数码科技