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的数组的扩展实例代码
Jul 09 Javascript
基于jQuery的淡入淡出可自动切换的幻灯插件打包下载
Sep 15 Javascript
玩转方法:call和apply
May 08 Javascript
jQuery中children()方法用法实例
Jan 07 Javascript
DOM节点删除函数removeChild()用法实例
Jan 12 Javascript
javascript实现获取服务器时间
May 19 Javascript
javascript产生随机数方法汇总
Jan 25 Javascript
详解js中的apply与call的用法
Jul 30 Javascript
vue表单绑定实现多选框和下拉列表的实例
Aug 12 Javascript
详解webpack的配置文件entry与output
Aug 21 Javascript
详解element-ui中el-select的默认选择项问题
Aug 02 Javascript
vue 解决mintui弹窗弹起来,底部页面滚动bug问题
Nov 12 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
elgg 获取文件图标地址的方法
2010/03/20 PHP
php数组生成html下拉列表的方法
2015/07/20 PHP
Yii2框架实现注册和登录教程
2016/09/30 PHP
pjblog中的UBBCode.js
2007/04/25 Javascript
JQuery中上下文选择器实现方法
2015/05/18 Javascript
jQuery购物网页经典制作案例
2016/08/19 Javascript
jQuery监听文件上传实现进度条效果的方法
2016/10/16 Javascript
Javascript 链式作用域详细介绍
2017/02/23 Javascript
vue自定义filters过滤器
2018/04/26 Javascript
详解IOS微信上Vue单页面应用JSSDK签名失败解决方案
2018/11/14 Javascript
jQuery.parseJSON()函数详解
2019/02/28 jQuery
vue-router为激活的路由设置样式操作
2020/07/18 Javascript
three.js 实现露珠滴落动画效果的示例代码
2021/03/01 Javascript
[01:02:20]Mineski vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
在win和Linux系统中python命令行运行的不同
2016/07/03 Python
Python正则表达式实现截取成对括号的方法
2017/01/06 Python
python 用for循环实现1~n求和的实例
2019/02/01 Python
Django实现发送邮件功能
2019/07/18 Python
在Python中os.fork()产生子进程的例子
2019/08/08 Python
浅析pandas 数据结构中的DataFrame
2019/10/12 Python
Python爬虫爬取杭州24时温度并展示操作示例
2020/03/27 Python
Python中无限循环需要什么条件
2020/05/27 Python
Django封装交互接口代码
2020/07/12 Python
详解python with 上下文管理器
2020/09/02 Python
详解H5 活动页之移动端 REM 布局适配方法
2017/12/07 HTML / CSS
UNDONE手表官网:世界领先的定制手表品牌
2018/11/13 全球购物
随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
2014/01/18 面试题
科研先进个人典型材料
2014/01/31 职场文书
大学生见习报告范文
2014/11/03 职场文书
综合素质评价自我评价
2015/03/06 职场文书
2015年妇产科工作总结
2015/05/18 职场文书
党员身份证明材料
2015/06/19 职场文书
总经理聘用协议书
2015/09/21 职场文书
《窃读记》教学反思
2016/02/18 职场文书
2016简单的租房合同范本
2016/03/18 职场文书
python基础之停用词过滤详解
2021/04/21 Python