深入理解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 相关文章推荐
JQuery优缺点分析说明
Jun 09 Javascript
js 中 document.createEvent的用法
Aug 29 Javascript
jQuery EasyUI API 中文文档 DateTimeBox日期时间框
Oct 16 Javascript
setTimeout的延时为0时多个浏览器的区别
May 23 Javascript
JavaScript使用push方法添加一个元素到数组末尾用法实例
Apr 06 Javascript
浅析javascript函数表达式
Feb 10 Javascript
hovertree插件实现二级树形菜单(简单实用)
Dec 28 Javascript
如何学JavaScript?前辈的经验之谈
Dec 28 Javascript
Bootstrap3 多选和单选框(checkbox)
Dec 29 Javascript
Vue-Router2.X多种路由实现方式总结
Feb 09 Javascript
ionic2.0双击返回键退出应用
Sep 17 Javascript
JS控制下拉列表左右选择实例代码
May 08 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 分页类(模仿google)-面试题目解答
2009/09/13 PHP
PHP的异常处理类Exception的使用及说明
2012/06/13 PHP
PHP手机号码归属地查询代码(API接口/mysql)
2012/09/04 PHP
php生成图形验证码几种方法小结
2013/08/15 PHP
使用配置类定义Codeigniter全局变量
2014/06/12 PHP
php生成二维码
2015/08/10 PHP
PHP中file_get_contents函数抓取https地址出错的解决方法(两种方法)
2015/09/22 PHP
PHP实现json_decode不转义中文的方法
2017/05/20 PHP
PHP实现的MD5结合RSA签名算法实例
2017/10/07 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
在Laravel的Model层做数据缓存的实现
2019/09/26 PHP
js中的push和join方法使用介绍
2013/10/08 Javascript
jquery 字符串切割函数substring的用法说明
2014/02/11 Javascript
javascript弹出页面回传值的方法
2015/01/28 Javascript
angularjs表格分页功能详解
2016/01/21 Javascript
javascript实现PC网页里的拖拽效果
2016/03/14 Javascript
微信小程序之小豆瓣图书实例
2016/11/30 Javascript
详解vue.js 开发环境搭建最简单攻略
2017/06/12 Javascript
JS实现求数组起始项到终止项之和的方法【基于数组扩展函数】
2017/06/13 Javascript
JavaScript之排序函数_动力节点Java学院整理
2017/06/30 Javascript
Webpack框架核心概念(知识点整理)
2017/12/22 Javascript
使用flow来规范javascript的变量类型
2019/09/12 Javascript
python实现多线程暴力破解登陆路由器功能代码分享
2015/01/04 Python
举例讲解Python程序与系统shell交互的方式
2015/04/09 Python
详解Python中for循环的使用
2015/04/14 Python
Python 比较两个数组的元素的异同方法
2017/08/17 Python
python 实现在Excel末尾增加新行
2018/05/02 Python
Python装饰器模式定义与用法分析
2018/08/06 Python
Python单元测试unittest的具体使用示例
2018/12/17 Python
opencv与numpy的图像基本操作
2019/03/08 Python
django 2.2和mysql使用的常见问题
2019/07/18 Python
python中K-means算法基础知识点
2021/01/25 Python
求职信格式范本
2013/11/15 职场文书
清扬洗发水广告词
2014/03/14 职场文书
清明节网上祭英烈寄语2015
2015/03/04 职场文书
python中出现invalid syntax报错的几种原因分析
2022/02/12 Python