深入理解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 相关文章推荐
xmlHTTP实例
Oct 24 Javascript
给应用部分的js代码设定一个统一的入口
Jun 15 Javascript
Javascript学习笔记之 对象篇(四) : for in 循环
Jun 24 Javascript
在线引用最新jquery文件的实现方法
Aug 26 Javascript
bootstrap 下拉多选框进行多选传值问题代码分析
Feb 14 Javascript
原生JavaScript实现Tooltip浮动提示框特效
Mar 07 Javascript
详解JS数组Reduce()方法详解及高级技巧
Aug 18 Javascript
ES6扩展运算符的用途实例详解
Aug 20 Javascript
jquery+ajaxform+springboot控件实现数据更新功能
Jan 22 jQuery
详解Chai.js断言库API中文文档
Jan 31 Javascript
浅谈vue.js导入css库(elementUi)的方法
Mar 09 Javascript
JavaScript前端实现压缩图片功能
Mar 06 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
类的另类用法--数据的封装
2006/10/09 PHP
php面向对象的方法重载两种版本比较
2008/09/08 PHP
php计算函数执行时间的方法
2015/03/20 PHP
Zend Framework框架Smarty扩展实现方法
2016/03/22 PHP
php+layui数据表格实现数据分页渲染代码
2019/10/26 PHP
JQuery SELECT单选模拟jQuery.select.js
2009/11/12 Javascript
9行javascript代码获取QQ群成员具体实现
2013/10/16 Javascript
javascript文件中引用依赖的js文件的方法
2014/03/17 Javascript
nodejs之请求路由概述
2014/07/05 NodeJs
node.js回调函数之阻塞调用与非阻塞调用
2015/11/13 Javascript
jQuery事件委托之Safari
2016/07/05 Javascript
关于angularJs指令的Scope(作用域)介绍
2016/10/25 Javascript
微信小程序 开发工具快捷键整理
2016/10/31 Javascript
flag和jq on 的绑定多个对象和方法(必看)
2017/02/27 Javascript
Mobile Web开发基础之四--处理手机设备的横竖屏问题
2017/08/11 Javascript
Vue.js 实现微信公众号菜单编辑器功能(二)
2018/05/08 Javascript
[59:35]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#1COL VS Alliance第二局
2016/03/04 DOTA
Python的净值数据接口调用示例分享
2016/03/15 Python
用yum安装MySQLdb模块的步骤方法
2016/12/15 Python
Django中的CBV和FBV示例介绍
2018/02/25 Python
使用Python向C语言的链接库传递数组、结构体、指针类型的数据
2019/01/29 Python
详解如何在cmd命令窗口中搭建简单的python开发环境
2019/08/29 Python
Pytorch 计算误判率,计算准确率,计算召回率的例子
2020/01/18 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
Django Serializer HiddenField隐藏字段实例
2020/03/31 Python
倩碧英国官网:Clinique英国
2018/08/10 全球购物
给领导的致歉信范文
2014/01/13 职场文书
国培计划培训感言
2014/03/11 职场文书
机械系毕业生求职信
2014/05/28 职场文书
国际贸易系求职信
2014/08/09 职场文书
村主任群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
办公室主任个人对照检查材料思想汇报
2014/10/11 职场文书
python实现黄金分割法的示例代码
2021/04/28 Python
MySQL 可扩展设计的基本原则
2021/05/14 MySQL
Java 将PPT幻灯片转为HTML文件的实现思路
2021/06/11 Java/Android
如何利用golang运用mysql数据库
2022/03/13 Golang