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中的稀疏数组与密集数组[译]
Sep 17 Javascript
JavaScript实现节点的删除与序号重建实例
Aug 05 Javascript
jquery对dom节点的操作【推荐】
Apr 15 Javascript
微信小程序 数据访问实例详解
Oct 08 Javascript
利用jQuery对无序列表排序的简单方法
Oct 16 Javascript
js 轮播效果实例分享
Dec 28 Javascript
three.js实现3D影院的原理的代码分析
Dec 18 Javascript
Angular动态绑定样式及改变UI框架样式的方法小结
Sep 03 Javascript
Vue 中文本内容超出规定行数后展开收起的处理的实现方法
Apr 28 Javascript
vue-cli在 history模式下的配置详解
Nov 26 Javascript
vue过滤器实现日期格式化的案例分析
Jul 02 Javascript
vue+elementUI动态增加表单项并添加验证的代码详解
Dec 17 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
Laravel框架数据库CURD操作、连贯操作总结
2014/09/03 PHP
php的dl函数用法实例
2014/11/06 PHP
CI框架常用经典操作类总结(路由,伪静态,分页,session,验证码等)
2016/11/21 PHP
Laravel6.18.19如何优雅的切换发件账户
2020/06/14 PHP
动态调用css文件——jquery的应用
2007/02/20 Javascript
ASP SQL防注入的方法
2008/12/25 Javascript
JQuery将文本转化成JSON对象需要注意的问题
2011/05/09 Javascript
jquery图片放大功能简单实现
2013/08/01 Javascript
jquery 页面滚动到指定DIV实现代码
2013/09/25 Javascript
JS和JQUERY获取页面大小,滚动条位置,元素位置(示例代码)
2013/12/14 Javascript
JavaScript仿支付宝密码输入框
2015/12/29 Javascript
js仿QQ中对联系人向左滑动、滑出删除按钮的操作
2016/04/07 Javascript
Javascript计算二维数组重复值示例代码
2016/12/18 Javascript
使用snowfall.jquery.js实现爱心满屏飞的效果
2017/01/05 Javascript
百度地图API之百度地图退拽标记点获取经纬度的实现代码
2017/01/12 Javascript
JS验证不重复验证码
2017/02/10 Javascript
Vue 2.0在IE11中打开项目页面空白的问题解决
2017/07/16 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
vue的全局提示框组件实例代码
2018/02/26 Javascript
angular4强制刷新视图的方法
2018/10/09 Javascript
ES6 Generator函数的应用实例分析
2019/06/26 Javascript
react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
2019/11/12 Javascript
Python ValueError: invalid literal for int() with base 10 实用解决方法
2015/06/21 Python
python+selenium开发环境搭建图文教程
2017/08/11 Python
python difflib模块示例讲解
2017/09/13 Python
tensorflow1.0学习之模型的保存与恢复(Saver)
2018/04/23 Python
解决Python selenium get页面很慢时的问题
2019/01/30 Python
用uWSGI和Nginx部署Flask项目的方法示例
2019/05/05 Python
python交互模式下输入换行/输入多行命令的方法
2019/07/02 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
2019/08/21 Python
python 爬虫基本使用——统计杭电oj题目正确率并排序
2020/10/26 Python
Pop In A Box英国:Funko POP搪胶公仔
2019/05/27 全球购物
教师自我评价范例
2013/09/24 职场文书
高中生毕业学习总结的自我评价
2013/11/14 职场文书
《叶问2》观后感
2015/06/15 职场文书
运动会入场词
2015/07/18 职场文书