深入理解jQuery3.0的domManip函数

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 );
  };
} );

如图

内部调用如图

源码

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函数,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • jQuery 3.0 的 setter和getter 模式详解

    jQuery 的 setter/getter 共用一个函数,通过是否传参来表明它是何种意义.简单说传参它是 setter,不传它是 getter. 一个函数具有多种意义在编程语言中并不罕见,比如函数重载:一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数.重载的好处是减少了函数名的数量,避免了名字空间的污染,对于程序的可读性也大有裨益. 函数重载主要体现的两个方面,一是参数的类型.相同个数的参数类型不同可称为函数重载:二是参数的个数,个数不同也称为函数重载.注意,重载与函数的返回值并

  • jQuery 3.0十大新特性最终版发布

    jQuery 3.0 最终版发布了.jQuery 3.0将是jQuery的未来.但如果你需要IE6-8支持,您可以继续使用最新版本1.12. jQuery 3.0在日前发布了最终的全新版本.从2014年10月,jQuery团队对这个主要大版本进行维护开始,web开发者社区便一直在期待着这一刻的到来,终于在2016年6月他们迎来了这一个最终版www.lampbrother.net. 通过jQuery 3.0的版本更新说明,我们看到了一个保持着向后兼容的更轻便,更快速的jQuery.在本文中,我们将

  • 解决3.01版的jquery.form.js中文乱码问题的解决方法

    网上搜了很多方法,可能因为我用的这jquery.form.js是3.01版,也就是今年3月6日才发布的版本(汗...就是前天),所以普遍不太管用.至于低版本的是否管用,这个我没有去考证,但大部分还是不负责任的Copy Copy Copy .还有一些方法是在提交前对所有的值先编码,我觉得这个太麻烦,额外增加了不少的前端代码量,也就没有采取. 好吧,那还是自己来处理吧.首先我们要找到切入点,也就是解决问题的入口.既然我们是要对JS传递的数据进行编码,那么首先肯定要从数据的传递函数开始.我调用的是aj

  • jQuery3.0中的buildFragment私有函数详解

    时隔 3 个月,jQuery 团队终于发布了 3.0 Alpha 版本.有两个版本 jQuery compat 3.0 和 jQuery 3.0. jQuery compat 3.0 对应之前的 1.x, 兼容更多的浏览器,对于IE支持到 8.0 版本 jQuery 3.0 对应之前的 2.x,关注更新的浏览器,对于IE支持到 9.0 版本 此外, 3.0还增加了对 Yandex 浏览器的支持,一款来自俄罗斯的浏览器. 下面看下jQuery3.0中的buildFragment. 在 jQuery

  • jQuery 3.0中存在问题及解决办法

    jQuery 前阶段推出了3.0版本,改动非常大,如果要使用 3.0 的话,建议先仔细了解一下新特性,否则会引起一些小问题,例如下面的代码. 大家对jQuery 3.0十大新特性不了解的朋友可以参考下本篇文章. <html> <head> <meta charset="utf-8"> <script src="jquery-3.0.min.js"></script> <script> $(fun

  • 浅析jQuery 3.0中的Data

    jQuery 3.0 在6月9日正式发布了,3.0 也被称为下一代的 jQuery.这个版本从14年10月开始,其中发布过一次beta 版(2016/1/14,)和候选版(2016/05/20).一路走来,颇为不易. 一.Data浅析 jQuery 3.0 中的 Data 是内部使用的,定义为一个"类".一共用它创建了两个对象,dataPriv 和 dataUser.Data 有 1 个对象属性(expando)和类属性(uid),有 6 个方法,如下 下面分别解读 1.Data.ui

  • jQuery 3.0十大新特性

    jQuery 3.0在日前发布了最终的全新版本.从2014年10月,jQuery团队对这个主要大版本进行维护开始,web开发者社区便一直在期待着这一刻的到来,终于在2016年6月他们迎来了这一个最终版. 通过jQuery 3.0的版本更新说明 ,我们看到了一个保持着向后兼容的更轻便,更快速的jQuery.在本文中,我们将介绍一些令人眼前一亮的jQuery 3.0全新特性. 开始前的说明 如果你想要下载jQuery 3.0进行亲自实验,可以通过 该页面 进行下载.另外, 升级指南 和 源代码 也值

  • jQuery 3.0 的变化及使用方法

    jQuery ,是迄今为止世界上最流行的 JavaScript 库,一直是我们这些 Web 开发者的神器.自从它在 2006 年发布最初版本直到如今,已经有非常多的 Web 开发者在项目中引入了这个优秀的库来使开发工作变得更轻松. 时隔 3 个月,jQuery 团队终于发布了 3.0 Alpha 版本.有两个版本 jQuery compat 3.0 和 jQuery 3.0. •jQuery compat 3.0 对应之前的 1.x, 兼容更多的浏览器,对于IE支持到 8.0 版本 •jQuer

  • 深入理解jQuery3.0的domManip函数

    domManip 这个函数的历史由来已久,从 jQuery 1.0 版本开始便存在了,一直到最新的 jQuery 版本.可谓是元老级工具函数. domManip 的主要功能是为了实现 DOM 的插入和替换.具体共为以下 5 个函数服务 •内部后插入(append) •内部前插入(prepend) •外部前插入(before) •外部后插入(after) •替换元素 (replaceWith,1.9.x 之前的版本没有使用 domMainp) 而一个 each 就生成了另外 5 个函数:appen

  • 深入理解PHP 数组之count 函数

    count() PHP count() 函数用于计算数组中的单元数目或对象中的属性个数,返回数组的单元个数或对象中的属性个数. 语法: int count( mixed var [, int mode] )如果 var 是非数组的普通变量,则返回 1 ,对于不存在.未初始化或空数组返回 0 . 可选参数 mode 设为 COUNT_RECURSIVE(或 1),count() 将递归地对数组计数,这对计算多维数组的所有单元尤其有用,但 count() 识别不了无限递归.mode 的默认值是 0

  • 深入理解JavaScript中的箭头函数

    从一开始箭头就是 JavaScript 的一部分,在第一个 JavaScript 中就建议将内联的脚本代码包裹在 HTML 的注释中,这可以防止那些不支持 JavaScript 的浏览器错误滴将你的代码显示为明文.你也许写过下面这样的代码: <script language="javascript"> <!-- document.bgColor = "brown"; // red // --> </script> <scri

  • 理解javascript中的回调函数(callback)

    最近在看 express,满眼看去,到处是以函数作为参数的回调函数的使用.如果这个概念理解不了,nodejs.express 的代码就会看得一塌糊涂.比如: 复制代码 代码如下: app.use(function(req, res, next) {     var err = new Error('Not Found');     err.status = 404;     next(err); }); app是对象,use是方法,方法的参数是一个带参的匿名函数,函数体直接在后面给出了.这段代码

  • 深入理解Yii2.0乐观锁与悲观锁的原理与使用

    本文介绍了深入理解Yii2.0乐观锁与悲观锁的原理与使用,分享给大家,具体如下: Web应用往往面临多用户环境,这种情况下的并发写入控制, 几乎成为每个开发人员都必须掌握的一项技能. 在并发环境下,有可能会出现脏读(Dirty Read).不可重复读(Unrepeatable Read). 幻读(Phantom Read).更新丢失(Lost update)等情况.具体的表现可以自行搜索. 为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念. 这里我们都不作解释了,拿这些关键

  • vue3.0响应式函数原理详细

    目录 1.reactive 2.ref 3.toRefs 4.computed 前言: Vue3重写了响应式系统,和Vue2相比底层采用Proxy对象实现,在初始化的时候不需要遍历所有的属性再把属性通过defineProperty转换成get和set.另外如果有多层属性嵌套的话只有访问某个属性的时候才会递归处理下一级的属性所以Vue3中响应式系统的性能要比Vue2好. 接下来我们自己实现Vue3响应式系统的核心函数(reactive/ref/toRefs/computed/effect/trac

  • thinkphp3.0 模板中函数的使用

    变量的来源: 1 从php分配的变量,使用assign分配 2 系统变量 3 路径替换变量 不能使用函数的变量 变量输出快捷标签 {@var}//输出Session变量 和{$Think.session.var}等效 {#var}//输出Cookie变量 和{$Think.cookie.var}等效 {&var}//输出配置参数 和{$Think.config.var}等效 {%var}//输出语言变量 和{$Think.lang.var}等效 {.var}//输出Get变量 和{$Think.

  • 深入理解PHP中的count函数

    在PHP编程中,在遍历数组的时候经常需要先计算数组的长度作为循环结束的判断条件,而在PHP里面对数组的操作是很频繁的,因此count也算是一个常用函数,下面研究一下count函数的具体实现. 我在github上有对PHP源码更详细的注解.感兴趣的可以围观一下,给个star.PHP5.4源码注解.可以通过commit记录查看已添加的注解. count int count ( mixed $array_or_countable [, int $mode = COUNT_NORMAL ] ) coun

  • 深入理解JavaScript 中的匿名函数((function() {})();)与变量的作用域

    匿名函数:没有实际名字的函数. 匿名函数的作用: 1.通过匿名函数可以实现闭包,关于闭包在后面的文章中会重点讲解.在这里简单介绍一下:闭包是可以访问在函数作用域内定义的变量的函数.若要创建一个闭包,往往都需要用到匿名函数. 2.模拟块级作用域,减少全局变量.执行完匿名函数,存储在内存中相对应的变量会被销毁,从而节省内存.再者,在大型多人开发的项目中,使用块级作用域,会大大降低命名冲突的问题,从而避免产生灾难性的后果.自此开发者再也不必担心搞乱全局作用域了. 本章节重点给大家介绍JavaScrip

随机推荐