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 相关文章推荐
增强用户体验友好性之jquery easyui window 窗口关闭时的提示
Jun 22 Javascript
js数组Array sort方法使用深入分析
Feb 21 Javascript
经过绑定元素时会多次触发mouseover和mouseout事件
Feb 28 Javascript
原生js编写设为首页兼容ie、火狐和谷歌
Jun 05 Javascript
javascript面向对象之定义成员方法实例分析
Jan 13 Javascript
JS实现的竖向折叠菜单代码
Oct 21 Javascript
js实现完美兼容各大浏览器的人民币大小写相互转换
Oct 29 Javascript
JQuery实现文字无缝滚动效果示例代码(Marquee插件)
Mar 07 Javascript
JS实现不用中间变量temp 实现两个变量值得交换方法
Feb 04 Javascript
详解如何用babel转换es6的class语法
Apr 03 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
Apr 30 Javascript
JS制作简易计算器的实例代码
Jul 04 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
首页四格,首页五格For6.0(GBK)(UTF-8)[12种组合][9-18][版主安装测试通过]
2007/09/24 PHP
ThinkPHP连接数据库及主从数据库的设置教程
2014/08/22 PHP
PHP中的socket_read和socket_recv区别详解
2015/02/09 PHP
php强制用户转向www域名的方法
2015/06/19 PHP
计算世界完全对称日的js代码,粗糙版
2011/11/04 Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
2013/03/31 Javascript
JavaScript中的类(Class)详细介绍
2014/12/30 Javascript
jQuery+AJAX实现遮罩层登录验证界面(附源码)
2020/09/13 Javascript
JavaScript代码实现禁止右键、禁选择、禁粘贴、禁shift、禁ctrl、禁alt
2015/11/17 Javascript
基于JavaScript实现全屏透明遮罩div层锁屏效果
2016/01/26 Javascript
全面解析JS字符串和正则表达式中的match、replace、exec等函数
2016/07/01 Javascript
js 自带的 map() 方法全面了解
2016/08/16 Javascript
设置cookie指定时间失效(实例代码)
2017/05/28 Javascript
深入理解vue-loader如何使用
2017/06/06 Javascript
基于vue 实现token验证的实例代码
2017/12/14 Javascript
Bootstrap实现可折叠分组侧边导航菜单
2018/03/07 Javascript
20个必会的JavaScript面试题(小结)
2019/07/02 Javascript
通过实例了解Javascript柯里化流程
2020/03/03 Javascript
Vue v-for中的 input 或 select的值发生改变时触发事件操作
2020/08/31 Javascript
ant design vue 表格table 默认勾选几项的操作
2020/10/31 Javascript
[22:59]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python脚本实现下载合并SAE日志
2015/02/10 Python
python选择排序算法实例总结
2015/07/01 Python
pyqt5 实现多窗口跳转的方法
2019/06/19 Python
ansible动态Inventory主机清单配置遇到的坑
2020/01/19 Python
Python PIL库图片灰化处理
2020/04/07 Python
CSS3等相关属性制作分页导航实现代码
2012/12/24 HTML / CSS
HTML5 CSS3新的WEB标准和浏览器支持
2009/07/16 HTML / CSS
Cotton On南非:澳洲时尚平价品牌
2018/06/28 全球购物
若干个Java基础面试题
2015/05/19 面试题
办公自动化专业大学生职业规划书
2014/03/06 职场文书
大学生职业生涯规划书汇总
2014/03/20 职场文书
党员反对四风问题思想汇报
2014/09/12 职场文书
2014员工聘用协议书(最新版)
2014/11/24 职场文书
导游词之广州陈家祠
2019/10/21 职场文书
vscode内网访问服务器的方法
2022/06/28 Servers