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 相关文章推荐
利用webqq协议使用python登录qq发消息源码参考
Apr 08 Javascript
jQuery打印指定区域Html页面并自动分页
Jul 04 Javascript
javascript函数中参数传递问题示例探讨
Jul 31 Javascript
jQuery随手笔记之常用的jQuery操作DOM事件
Nov 29 Javascript
详解Bootstrap各式各样的按钮(推荐)
Dec 13 Javascript
纯JS实现表单验证实例
Dec 24 Javascript
Vue 第三方字体图标引入 Font Awesome的方法
Sep 28 Javascript
了解前端理论:rscss和rsjs
May 23 Javascript
实用的Vue开发技巧
May 30 Javascript
VUE DEMO之模拟登录个人中心页面之间数据传值实例
Oct 31 Javascript
vue实现公共方法抽离
Jul 31 Javascript
JavaScript实现原型封装轮播图
Dec 27 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
数据库中排序的对比及使用条件详解
2012/02/23 PHP
基于PHP服务端图片生成缩略图的方法详解
2013/06/20 PHP
php实现天干地支计算器示例
2014/03/14 PHP
单台服务器的PHP进程之间实现共享内存的方法
2014/06/13 PHP
Laravel中使用阿里云OSS Composer包分享
2015/02/10 PHP
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
javascript从右边截取指定字符串的三种实现方法
2013/11/29 Javascript
Get中文乱码IE浏览器Get中文乱码解决方案
2013/12/26 Javascript
javascript校验价格合法性实例(必须输入2位小数)
2014/05/05 Javascript
JavaScript实现找出数组中最长的连续数字序列
2014/09/03 Javascript
jQuery ajax serialize() 方法使用示例
2014/11/02 Javascript
JQuery 在文档中查找指定name的元素并移除的实现方法
2016/05/19 Javascript
js图片上传前预览功能(兼容所有浏览器)
2016/08/24 Javascript
jQuery 获取遍历获取table中每一个tr中的第一个td的方法
2016/10/05 Javascript
微信小程序 Windows2008 R2服务器配置TLS1.2方法
2016/12/05 Javascript
如何写好你的JavaScript【推荐】
2017/03/02 Javascript
浅谈React Native 中组件的生命周期
2017/09/08 Javascript
vue二级菜单导航点击选中事件的方法
2018/09/12 Javascript
微信小程序 轮播图实现原理及优化详解
2019/09/29 Javascript
vue 解决addRoutes多次添加路由重复的操作
2020/08/04 Javascript
用Python编写一个每天都在系统下新建一个文件夹的脚本
2015/05/04 Python
tensorflow建立一个简单的神经网络的方法
2018/02/10 Python
Python cookbook(字符串与文本)在字符串的开头或结尾处进行文本匹配操作
2018/04/20 Python
Ubuntu下Anaconda和Pycharm配置方法详解
2019/06/14 Python
Python用Try语句捕获异常的实例方法
2019/06/26 Python
CSS中的字体大小设置属性总结
2016/05/24 HTML / CSS
Qoo10台湾站:亚洲领先的在线市场
2018/05/15 全球购物
SNIDEL官网:日本VIVI杂志人气少女第一品牌
2020/03/12 全球购物
荷兰最大的鞋子、服装和运动折扣店:Bristol
2021/01/07 全球购物
公司合作协议书范本
2014/04/18 职场文书
综合实践活动总结
2014/05/05 职场文书
2015共产党员公开承诺书
2015/01/22 职场文书
Python离线安装openpyxl模块的步骤
2021/03/30 Python
Django rest framework如何自定义用户表
2021/06/09 Python
分析Netty直接内存原理及应用
2021/06/14 Java/Android
MySQL 主从复制数据不一致的解决方法
2022/03/18 MySQL