深入理解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查看html源文件
Nov 08 Javascript
Google Maps API地图应用示例分享
Oct 23 Javascript
jQuery使用之标记元素属性用法实例
Jan 19 Javascript
JavaScript数据结构和算法之图和图算法
Feb 11 Javascript
JavaScript生成验证码并实现验证功能
Sep 24 Javascript
为JQuery EasyUI 表单组件增加焦点切换功能的方法
Apr 13 jQuery
vue时间格式化实例代码
Jun 13 Javascript
基于node.js制作简单爬虫教程
Jun 29 Javascript
vue使用axios跨域请求数据问题详解
Oct 18 Javascript
JavaScript中的一些隐式转换和总结(推荐)
Dec 22 Javascript
no-vnc和node.js实现web远程桌面的完整步骤
Aug 11 Javascript
React中使用UMEditor的方法示例
Dec 27 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生成静态页
2006/11/25 PHP
PHP MemCached高级缓存配置图文教程
2010/08/05 PHP
THINKPHP内容分页代码分享
2015/01/14 PHP
ThinkPHP 3.2 版本升级了哪些内容
2015/03/05 PHP
图文介绍PHP添加Redis模块及连接
2015/07/28 PHP
thinkphp中字符截取函数msubstr()用法分析
2016/01/09 PHP
PHP排序算法之归并排序(Merging Sort)实例详解
2018/04/21 PHP
javascript 判断字符串是否包含某字符串及indexOf使用示例
2013/10/18 Javascript
利用js制作html table分页示例(js实现分页)
2014/04/25 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
2014/05/08 Javascript
一个可以增加和删除行的table并可编辑表格中内容
2014/06/16 Javascript
使用delegate方法为一个tr标签加一个链接
2014/06/27 Javascript
纯javascript模仿微信打飞机小游戏
2015/08/20 Javascript
JS实现的跨浏览器解析XML文件实例
2016/06/21 Javascript
jQuery插件学习教程之SlidesJs轮播+Validation验证
2016/07/12 Javascript
jQuery 选择器(61种)整理总结
2016/09/26 Javascript
jquery实现简单实用的轮播器
2017/05/23 jQuery
老生常谈Bootstrap媒体对象
2017/07/06 Javascript
关于vue-router的那些事儿
2018/05/23 Javascript
nvm、nrm、npm 安装和使用详解(小结)
2019/01/17 Javascript
axios实现文件上传并获取进度
2020/03/25 Javascript
Nodejs + sequelize 实现增删改查操作
2020/11/07 NodeJs
Python实现的求解最小公倍数算法示例
2018/05/03 Python
Python内置异常类型全面汇总
2020/05/28 Python
Python3爬虫中Splash的知识总结
2020/07/10 Python
python boto和boto3操作bucket的示例
2020/10/30 Python
Python try except else使用详解
2021/01/12 Python
西班牙英格列斯百货法国官网:El Corte Inglés法国
2017/07/09 全球购物
说出数据连接池的工作机制是什么?
2013/04/19 面试题
高中生学习生活的自我评价
2013/10/09 职场文书
学生安全教育材料
2014/02/14 职场文书
人民调解员先进事迹材料
2014/05/08 职场文书
五四演讲稿范文
2014/09/03 职场文书
公司禁烟通知
2015/04/23 职场文书
2015年防汛工作总结
2015/05/15 职场文书
创业计划书之干洗店
2019/09/10 职场文书