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


Posted in Javascript onAugust 16, 2016

时隔 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。

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

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

如下图

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

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 数组中

如图示

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

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

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

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

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

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

以上所述是小编给大家介绍的jQuery3.0中的buildFragment私有函数详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js removeChild 障眼法 可能出现的错误
Oct 06 Javascript
jquery 表格分页等操作实现代码(pagedown,pageup)
Apr 11 Javascript
使用jquery为table动态添加行的实现代码
Mar 30 Javascript
JavaScript打印iframe内容示例代码
Aug 20 Javascript
EasyUI实现第二层弹出框的方法
Mar 01 Javascript
JS实现iframe自适应高度的方法示例
Jan 07 Javascript
JavaScript 异步调用
Oct 25 Javascript
JavaScript学习笔记之DOM操作实例分析
Jan 08 Javascript
Node.js中Koa2在控制台输出请求日志的方法示例
May 02 Javascript
微信小程序模板消息推送的两种实现方式
Aug 27 Javascript
javascript刷新父页面方法汇总详解
Oct 10 Javascript
JavaScript函数IIFE使用详解
Oct 21 Javascript
js 自带的 map() 方法全面了解
Aug 16 #Javascript
JavaScript实战之带收放动画效果的导航菜单
Aug 16 #Javascript
js 自带的sort() 方法全面了解
Aug 16 #Javascript
JavaScript实战之菜单特效
Aug 16 #Javascript
深入理解js generator数据类型
Aug 16 #Javascript
js 创建对象 经典模式全面了解
Aug 16 #Javascript
js 上传文件预览的简单实例
Aug 16 #Javascript
You might like
咖啡与牛奶
2021/03/03 冲泡冲煮
Wordpress 相册插件 NextGEN-Gallery 添加目录将中文转为拼音的解决办法
2010/12/29 PHP
解析PHP可变函数的经典用法
2013/06/20 PHP
PHP用strstr()函数阻止垃圾评论(通过判断a标记)
2013/09/28 PHP
php限制ip地址范围的方法
2015/03/31 PHP
php使用ob_flush不能每隔一秒输出原理分析
2015/06/02 PHP
php5.x禁用eval的操作方法
2018/10/19 PHP
js实现iframe动态调整高度的代码
2008/01/06 Javascript
js弹出确认是否删除对话框
2014/03/27 Javascript
JS+CSS实现表格高亮的方法
2015/08/05 Javascript
jQuery提示插件qTip2用法分析(支持ajax及多种样式)
2016/06/08 Javascript
jQuery绑定自定义事件的魔法升级版
2016/06/30 Javascript
深入理解vue-loader如何使用
2017/06/06 Javascript
用JavaScript做简易的购物车的代码示例
2017/10/20 Javascript
vue2.0实现音乐/视频播放进度条组件
2018/06/06 Javascript
vue里input根据value改变背景色的实例
2018/09/29 Javascript
Vue.js实现的购物车功能详解
2019/01/27 Javascript
JavaScript面试技巧之数组的一些不low操作
2019/03/22 Javascript
layui select 禁止点击的实现方法
2019/09/05 Javascript
微信小程序接入腾讯云验证码的方法步骤
2020/01/07 Javascript
js回调函数原理与用法案例分析
2020/03/04 Javascript
node koa2 ssr项目搭建的方法步骤
2020/12/11 Javascript
js 执行上下文和作用域的相关总结
2021/02/08 Javascript
[01:35]2018完美盛典章节片——共竞
2018/12/17 DOTA
Python中的装饰器用法详解
2015/01/14 Python
python实现Floyd算法
2018/01/03 Python
在windows下使用python进行串口通讯的方法
2019/07/02 Python
python爬虫 模拟登录人人网过程解析
2019/07/31 Python
TensorFlow实现自定义Op方式
2020/02/04 Python
python利用opencv实现SIFT特征提取与匹配
2020/03/05 Python
Django中ORM的基本使用教程
2020/12/22 Python
办公室秘书自我鉴定
2014/01/18 职场文书
继承公证书
2014/04/09 职场文书
计算机多媒体专业自荐信
2014/07/04 职场文书
python如何正确使用yield
2021/05/21 Python
pt-archiver 主键自增
2022/04/26 MySQL