在 jQuery3.0中,buildFragment 是一个私有函数,用来构建一个包含子节点 fragment 对象。这个 fragment 在 DOM1 中就已经有了,所有浏览器都支持。当频繁操作(添加、插入) DOM 时使用该方法可以提高性能,John resig 做过一个测试及一篇博客

jQuery3.0 中 buildFragment 只在 domManip 和 jQuery.parseHTML 中使用,domManip 则被 DOM 操作如 append、prepend、before、after 等方法的所依赖。如下图

buildFragment 函数有 5 个参数,源码如下

function buildFragment( elems, context, scripts, selection, ignored ) {
var elem, tmp, tag, wrap, contains, j,
fragment = context.createDocumentFragment(),
nodes = [],
i = 0,
l = elems.length; for ( ; i < l; i++ ) {
elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly
if ( jQuery.type( elem ) === "object" ) { // Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node
} else if ( !rhtml.test( elem ) ) {
nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes
} else {
tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); // Deserialize a standard representation
tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
wrap = wrapMap[ tag ] || wrapMap._default;
tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; // Descend through wrappers to the right content
j = wrap[ 0 ];
while ( j-- ) {
tmp = tmp.lastChild;
} // Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
jQuery.merge( nodes, tmp.childNodes ); // Remember the top-level container
tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392)
tmp.textContent = "";
}
}
} // Remove wrapper from fragment
fragment.textContent = ""; i = 0;
while ( ( elem = nodes[ i++ ] ) ) { // Skip elements already in the context collection (trac-4087)
if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
if ( ignored ) {
ignored.push( elem );
}
continue;
} contains = jQuery.contains( elem.ownerDocument, elem ); // Append to fragment
tmp = getAll( fragment.appendChild( elem ), "script" ); // Preserve script evaluation history
if ( contains ) {
setGlobalEval( tmp );
} // Capture executables
if ( scripts ) {
j = 0;
while ( ( elem = tmp[ j++ ] ) ) {
if ( rscriptType.test( elem.type || "" ) ) {
scripts.push( elem );
}
}
}
} return fragment;
}

该方法主要执行步骤

  1. 通过第二个参数 content 创建 fragment
  2. 通过第一个参数 elems 构建 nodes ,将 elems 内元素转成 DOM 元素存放于数组 nodes 中
  3. 将 nodes 里元素循环放入添加到文档碎片 fragment 上
  4. 返回 fragment

重点在第 2 步,构建 nodes,有 3 种情形

  1. elem 是 DOM 元素(根据nodeType判断),直接放入 nodes 数组中
  2. elem 是字符串且不是 HTML tag,创建文本节点对象(textNode),放入 nodes 数组中
  3. elem 是字符串且是 HTML tag,将其转成 DOM 元素,放入 nodes 数组中

如图示

后面的两个参数需要注意下

1. 最后两个参数 selection 和 ignored 只在 replaceWith 方法里使用。需要了解的是 replaceWith 只做节点替换,不会替换先前元素的所有数据(Data),比如绑定事件,$.data 都不会被新元素拥有。

2. scripts 参数只在 jQuery.parseHTML 方法里使用(domManip里传false),当 jQuery.parseHTML 的第三个参数 keepScripts 为 false 时将删除节点里所有的 script tag

buildFragment 在 jQuery 各个版本中的演变

  1. 1.0.x ~ 1.3.x 中没有 buildFragment 函数,即没有抽取出该函数为 domManip 服务
  2. 1.4.x 中首次引入 buildFragment ,当时是挂在 jQuery 上的静态方法,有三个参数 args, nodes, scripts。一直到2.x.x 依然是公开可以访问的
  3. 3.x.x 开始 buildFragment 变成了一个私有函数,只能在 jQuery 代码内部访问,客户端程序员无法访问

jQuery 3.0的buildFragment的更多相关文章

  1. jQuery 2.0.3 源码分析core - 选择器

         声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢!      打开jQuery源码,一眼看去到处都充斥着正则表达式,jQuery框架的基础就是查询了,查询文档元素对象 ...

  2. jQuery 3.0的domManip浅析

    domManip 这个函数的历史由来已久,从 jQuery 1.0 版本开始便存在了,一直到最新的 jQuery 版本.可谓是元老级工具函数. domManip 的主要功能是为了实现 DOM 的插入和 ...

  3. jQuery 3.0 的 Data 浅析

    jQuery 3.0 在6月9日正式发布了,3.0 也被称为下一代的 jQuery .这个版本从14年10月开始,其中发布过一次beta 版(2016/1/14,)和候选版(2016/05/20).一 ...

  4. jQuery 3.0正式发布

    jQuery 基金会刚刚发布了该 JavaScript 框架的 3.0 版本,并且首次抛弃了对老旧的 IE 浏览器的支持.jQuery 3.0 的工作始于 2014 年 10 月,其最初目标是在 2. ...

  5. jQuery 3.0 的变化

    时隔 3 个月,jQuery 团队终于发布了 3.0 Alpha 版本.有两个版本 jQuery compat 3.0 和 jQuery 3.0. jQuery compat 3.0 对应之前的 1. ...

  6. jQuery 2.0发布,不再支持IE6/7/8

    有时发现jQuery库引用的都对,javascript代码写的也没问题,可是jquery就是出现问题,额--我发现换个jquery库就没问题了,长时间不关注jquery的问题而已: 很多人都没有使用最 ...

  7. PJax在jQuery 3.0无法运行问题修复

    PJax在jQuery 3.0无法运行 [现象] 页面报错:Uncaught TypeError: Cannot read property 'push' of undefined [原因] jQue ...

  8. jQuery 3.0 的 Data

    jQuery 3.0 的 Data Snandy If you cannot hear the sound of the genuine in you, you will all of your li ...

  9. jQuery 2.0.3 源码分析Sizzle引擎解析原理

    jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...

随机推荐

  1. Android APP压力测试(三)之Monkey日志自动分析脚本

    Android APP压力测试(三) 之Monkey日志自动分析脚本 前言 上次说要分享Monkey日志的分析脚本,这次贴出来分享一下,废话不多说,请看正文. [目录] 1.Monkey日志分析脚本 ...

  2. [Java IO]04_系统标准IO

    System表示系统类,它有3个与 Java IO 有关的常量. System.out——系统标准输出 System.in——系统标准输入 System.err——错误信息输出 System.out ...

  3. Windows下程序启动时出现0xc000007b错误的解决方案

    一.背景介绍 不久前用Qt开发了一款小工具在公司使用,Debug运行时一切正常.可是当Release编译发布打包之后,运行时弹出这样的提示框: 略一思考,首先排除了DLL缺失的可能性.我知道Qt应用程 ...

  4. jquery制作论坛或社交网站的每天打卡签到特效

    效果:http://hovertree.com/texiao/jquery/50/ 现在许多社区,购物等网站都设置签到功能,打开可以收获经验.虚拟币等,提高用户粘性,增加浏览量,是一个不错的功能.本文 ...

  5. WCF入门教程(一)简介

    WCF入门教程(一)简介 1.WCF是什么? WCF( Windows Communication Foundation), 是Microsoft为构建面向服务的应用提供的分布式通信编程框架,是.NE ...

  6. webserver[实时查询当天的天气情况]

    1.webserver是什么? 日常生活中经常会使用到webserver,注册时,会收到验证码,购买东西时,会收到短信,假如,A公司网站和B公司合作,那么A公司注册对的用户可以直接推送给B网站,那怎么 ...

  7. liunx命令

    关机 (系统的关机.重启以及登出 ) shutdown -h now 关闭系统(1) init 0 关闭系统(2) telinit 0 关闭系统(3) shutdown -h hours:minute ...

  8. GridView嵌套在ScrollView里只有一行的问题

    遇到这个问题 网上找到的解决办法: 方法一:就是上面说的通过计算出来ListView或者GridView中的子列高度和 进行显示:public void setListViewHeightBasedO ...

  9. 17、ASP.NET MVC入门到精通——Spring.net入门

    Spring.NET环境准备 pring.NET 1.3.2下载地址:http://down.51cto.com/data/861700 下载后解压 Spring.NET-1.3.2.7z:这个里面有 ...

  10. Hibernate总结(一)

    Hibernate为了提高性能,提供了缓存与快照机制. 它的缓存分为一级缓存与二级缓存. Hibernate一级缓存:当一个事务中执行一次Sql语句时,就将返回的结果存储在Session中的Map集合 ...