jQuery 3.0的buildFragment
在 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;
}
该方法主要执行步骤
- 通过第二个参数 content 创建 fragment
- 通过第一个参数 elems 构建 nodes ,将 elems 内元素转成 DOM 元素存放于数组 nodes 中
- 将 nodes 里元素循环放入添加到文档碎片 fragment 上
- 返回 fragment
重点在第 2 步,构建 nodes,有 3 种情形
- elem 是 DOM 元素(根据nodeType判断),直接放入 nodes 数组中
- elem 是字符串且不是 HTML tag,创建文本节点对象(textNode),放入 nodes 数组中
- 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.0.x ~ 1.3.x 中没有 buildFragment 函数,即没有抽取出该函数为 domManip 服务
- 1.4.x 中首次引入 buildFragment ,当时是挂在 jQuery 上的静态方法,有三个参数 args, nodes, scripts。一直到2.x.x 依然是公开可以访问的
- 3.x.x 开始 buildFragment 变成了一个私有函数,只能在 jQuery 代码内部访问,客户端程序员无法访问
jQuery 3.0的buildFragment的更多相关文章
- jQuery 2.0.3 源码分析core - 选择器
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 打开jQuery源码,一眼看去到处都充斥着正则表达式,jQuery框架的基础就是查询了,查询文档元素对象 ...
- jQuery 3.0的domManip浅析
domManip 这个函数的历史由来已久,从 jQuery 1.0 版本开始便存在了,一直到最新的 jQuery 版本.可谓是元老级工具函数. domManip 的主要功能是为了实现 DOM 的插入和 ...
- jQuery 3.0 的 Data 浅析
jQuery 3.0 在6月9日正式发布了,3.0 也被称为下一代的 jQuery .这个版本从14年10月开始,其中发布过一次beta 版(2016/1/14,)和候选版(2016/05/20).一 ...
- jQuery 3.0正式发布
jQuery 基金会刚刚发布了该 JavaScript 框架的 3.0 版本,并且首次抛弃了对老旧的 IE 浏览器的支持.jQuery 3.0 的工作始于 2014 年 10 月,其最初目标是在 2. ...
- jQuery 3.0 的变化
时隔 3 个月,jQuery 团队终于发布了 3.0 Alpha 版本.有两个版本 jQuery compat 3.0 和 jQuery 3.0. jQuery compat 3.0 对应之前的 1. ...
- jQuery 2.0发布,不再支持IE6/7/8
有时发现jQuery库引用的都对,javascript代码写的也没问题,可是jquery就是出现问题,额--我发现换个jquery库就没问题了,长时间不关注jquery的问题而已: 很多人都没有使用最 ...
- PJax在jQuery 3.0无法运行问题修复
PJax在jQuery 3.0无法运行 [现象] 页面报错:Uncaught TypeError: Cannot read property 'push' of undefined [原因] jQue ...
- 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 ...
- jQuery 2.0.3 源码分析Sizzle引擎解析原理
jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...
随机推荐
- Circuit Breaker Pattern(断路器模式)
Handle faults that may take a variable amount of time to rectify when connecting to a remote service ...
- C#获取图片的后缀名
最近在学习过程中遇到一个问题,就是如何获取图片的格式,对于一张知道全路径的照片,如果其路径包含后缀名的话,要取得后缀名,只需要一行代码即可: var ext = System.IO.Path.GetE ...
- Android声音播放实例代码
布局文件: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=&q ...
- C#播放MP3源代码
代码如下: using System; using System.Runtime.InteropServices; using System.Text; using System.IO ; using ...
- 委托 lambda表达式浅显理解
方法不能跟变量一样当参数传递,怎么办,C#定义了委托,就可以把方法当变量一样传递了,为了简单,匿名方法传递,省得再声明方法了:再简单,lambda表达式传递,比匿名方法更直观. public dele ...
- 设置Textview最大长度,超出显示省略号
<TextView android:id="@+id/tvUserNameUgcListItem" android:layout_height="@dimen/dp ...
- 转载:《TypeScript 中文入门教程》 15、可迭代性
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 可迭代性 当一个对象实现了Symbol.iterator属性时,我们认为它是可迭代的. ...
- 用eclipse做项目中常遇到的问题-如何创建并读取properties文件
在用eclipse做项目开发的时候我们常常会将一些重要的内容写在配置文件里面, 特别是连接数据库的url,username,password等信息,我们常常会新建一个properties文件将所有信息 ...
- python基础之条件控制与循环
Python3 条件控制 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户 ...
- 【requireJS路径加载】与程序员小卡的交流
这两天正好看到了程序员小卡同学的一篇博客,里面对requireJS路径的解析做了一些说明,里面有点问题待解决,我这里正好知道一点,所以整理成文,不知对小卡同学是否有帮助. http://www.cnb ...