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实现用方向键控制层的上下左右移动
Jan 13 Javascript
JQuery中使文本框获得焦点的方法实例分析
Feb 28 Javascript
深入理解JavaScript系列(26):设计模式之构造函数模式详解
Mar 03 Javascript
在JavaScript中用getMinutes()方法返回指定的分时刻
Jun 10 Javascript
JavaScript的Backbone.js框架的一些使用建议整理
Feb 14 Javascript
基于BootStrap Metronic开发框架经验小结【七】数据的导入、导出及附件的查看处理
May 12 Javascript
Angular ng-repeat 对象和数组遍历实例
Sep 14 Javascript
jsp 自动编译机制详细介绍
Dec 01 Javascript
jQuery实现选中行变色效果(实例讲解)
Jul 06 jQuery
你应该知道的几类npm依赖包管理详解
Oct 06 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
Sep 12 Javascript
详解如何在微信小程序开发中正确的使用vant ui组件
Sep 13 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
PHP实现电商订单自动确认收货redis队列
2017/05/17 PHP
PHP使用反向Ajax技术实现在线客服系统详解
2019/07/01 PHP
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
javascript中clone对象详解
2014/12/03 Javascript
Javascript中typeof 用法小结
2015/05/12 Javascript
JS右下角广告窗口代码(可收缩、展开及关闭)
2015/09/04 Javascript
干货分享:让你分分钟学会javascript闭包
2015/12/25 Javascript
Bootstrap基本插件学习笔记之Alert警告框(20)
2016/12/08 Javascript
Angular 2父子组件之间共享服务通信的实现
2017/07/04 Javascript
浅谈angularJS的$watch失效问题的解决方案
2017/08/11 Javascript
Javascript的console['']常用输入方法汇总
2018/04/26 Javascript
JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法示例
2018/07/27 Javascript
一个因@click.stop引发的bug的解决
2019/01/08 Javascript
js实现3D粒子酷炫动态旋转特效
2020/09/13 Javascript
[01:00:52]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第一场
2018/04/05 DOTA
[53:10]Secret vs Pain 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python中使用OpenCV进行人脸检测的例子
2014/04/18 Python
跟老齐学Python之有容乃大的list(2)
2014/09/15 Python
详解python如何调用C/C++底层库与互相传值
2016/08/10 Python
python基础之包的导入和__init__.py的介绍
2018/01/08 Python
python实现Decorator模式实例代码
2018/02/09 Python
Python3利用Dlib19.7实现摄像头人脸识别的方法
2018/05/11 Python
pandas重新生成索引的方法
2018/11/06 Python
Python类装饰器实现方法详解
2018/12/21 Python
python多线程并发让两个LED同时亮的方法
2019/02/18 Python
python调用pyaudio使用麦克风录制wav声音文件的教程
2019/06/26 Python
Python操作word文档插入图片和表格的实例演示
2020/10/25 Python
佳能英国官方网站:Canon UK
2017/08/08 全球购物
美国亚洲时尚和美容产品的一站式网上商店:Stylevana
2019/09/05 全球购物
毕业生求职推荐信
2013/11/04 职场文书
农村党支部先进事迹
2014/01/14 职场文书
2014年材料员工作总结
2014/11/19 职场文书
2014年心理健康教育工作总结
2014/12/06 职场文书
奖学金感谢信
2015/01/21 职场文书
幼儿园保育员随笔
2015/08/14 职场文书
springboot用户数据修改的详细实现
2022/04/06 Java/Android