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 相关文章推荐
在JavaScript中,为什么要尽可能使用局部变量?
Apr 06 Javascript
学习ExtJS(一) 之基础前提
Oct 07 Javascript
JavaScript 序列化对象实现代码
Dec 18 Javascript
js树插件zTree获取所有选中节点数据的方法
Jan 28 Javascript
JavaScript实现重置表单(reset)的方法
Apr 02 Javascript
jQuery点击其他地方时菜单消失的实现方法
Apr 22 Javascript
JavaScript之实现一个简单的Vue示例
Jan 17 Javascript
在vue中动态添加class类进行显示隐藏实例
Nov 09 Javascript
Vue实现浏览器打印功能的代码
Apr 17 Javascript
JavaScrip如果基于url实现图片下载
Jul 03 Javascript
jquery实现简易验证插件封装
Sep 13 jQuery
详解gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
Nov 27 Vue.js
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
PHP生成带有雪花背景的验证码
2008/09/28 PHP
php操作mysqli(示例代码)
2013/10/28 PHP
解决PhpMyAdmin中导入2M以上大文件限制的方法分享
2014/06/06 PHP
PHP中array_map与array_column之间的关系分析
2014/08/19 PHP
php数组函数array_walk用法示例
2016/05/26 PHP
thinkphp分页集成实例
2017/07/24 PHP
Firefox window.close()的使用注意事项
2009/04/11 Javascript
jQuery 拖动层(在可视区域范围内)
2012/05/24 Javascript
javascript仿qq界面的折叠菜单实现代码
2012/12/12 Javascript
javascript根据像素点取位置示例
2014/01/27 Javascript
jQuery自带的一些常用方法总结
2014/09/03 Javascript
jQuery实现响应浏览器缩放大小并改变背景颜色
2014/10/31 Javascript
JavaScript显示当前文档最后修改日期的方法
2015/03/19 Javascript
JavaScript中使用自然对数ln的方法
2015/06/14 Javascript
将List对象列表转换成JSON格式的类实现方法
2016/07/04 Javascript
微信小程序开发之实现自定义Toast弹框
2017/06/08 Javascript
Vue 实现从文件中获取文本信息的方法详解
2019/10/16 Javascript
Servlet返回的数据js解析2种方法
2019/12/12 Javascript
[48:32]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 LGD vs VG
2018/04/01 DOTA
Python中的pprint折腾记
2015/01/21 Python
Python正则表达式经典入门教程
2017/05/22 Python
Python二叉树的定义及常用遍历算法分析
2017/11/24 Python
在pandas中一次性删除dataframe的多个列方法
2018/04/10 Python
python程序 线程队列queue使用方法解析
2019/09/23 Python
简单了解Python3 bytes和str类型的区别和联系
2019/12/19 Python
python drf各类组件的用法和作用
2021/01/12 Python
BLACKMORES澳洲官网:澳大利亚排名第一的保健品牌
2018/09/27 全球购物
编写用C语言实现的求n阶阶乘问题的递归算法
2014/10/21 面试题
网上卖盒饭创业计划书
2014/01/26 职场文书
物业保安员岗位职责制度
2014/01/30 职场文书
让生命充满爱演讲稿
2014/05/10 职场文书
博士给导师的自荐信
2015/03/06 职场文书
2015年青年教师工作总结
2015/05/25 职场文书
毕业论文答辩开场白和结束语
2015/05/27 职场文书
一定要知道的 25 个 Vue 技巧
2021/11/02 Vue.js
聊聊redis-dump工具安装问题
2022/01/18 Redis