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数字输入框(包括最大值最小值限制和四舍五入)
Nov 24 Javascript
JavaScript 常用函数
Dec 30 Javascript
Extjs学习笔记之六 面版
Jan 08 Javascript
基于Jquery的跨域传输数据(JSONP)
Mar 10 Javascript
Uglifyjs(JS代码优化工具)入门 安装使用
Apr 13 Javascript
js捕获鼠标右键菜单中的粘帖事件实现代码
Apr 01 Javascript
jQuery插件分享之分页插件jqPagination
Jun 06 Javascript
Node.js事件循环(Event Loop)和线程池详解
Jan 28 Javascript
javascript中动态函数用法实例分析
May 14 Javascript
javascript实现根据函数名称字符串动态执行函数的方法示例
Dec 28 Javascript
新手必须知的Node.js 4个JavaScript基本概念
Sep 16 Javascript
解决vue打包报错Unexpected token: punc的问题
Oct 24 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图片上传程序
2008/03/27 PHP
FireFox浏览器使用Javascript上传大文件
2013/10/30 PHP
ThinkPHP框架搭建及常见问题(XAMPP安装失败、Apache/MySQL启动失败)
2016/04/15 PHP
thinkPHP基于ajax实现的菜单与分页示例
2016/07/12 PHP
Thinkphp5+uploadify实现的文件上传功能示例
2018/05/26 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
2020/02/18 PHP
css把超出的部分显示为省略号的方法兼容火狐
2008/07/23 Javascript
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
获取css样式表内样式的js函数currentStyle(IE),defaultView(FF)
2011/02/14 Javascript
JS匀速运动演示示例代码
2013/11/26 Javascript
通过复制Table生成word和excel的javascript代码
2014/01/20 Javascript
js获取json元素数量的方法
2015/01/27 Javascript
web前端开发JQuery常用实例代码片段(50个)
2015/08/28 Javascript
WebSocket+node.js创建即时通信的Web聊天服务器
2016/08/08 Javascript
关于两个jQuery(js)特效冲突的bug的解决办法
2016/09/04 Javascript
把多个JavaScript函数绑定到onload事件处理函数上的方法
2016/09/04 Javascript
AngularJS过滤器filter用法实例分析
2016/11/04 Javascript
如何实现星星评价(jquery.raty.js插件)
2016/12/21 Javascript
详解Vue2.X的路由管理记录之 钩子函数(切割流水线)
2017/05/02 Javascript
解决layui前端框架 form表单,table表等内置控件不显示的问题
2018/08/19 Javascript
vue-cli构建vue项目的步骤详解
2019/01/27 Javascript
vue基础之data存储数据及v-for循环用法示例
2019/03/08 Javascript
vue实现的请求服务器端API接口示例
2019/05/25 Javascript
Javascript原生ajax请求代码实例
2020/02/20 Javascript
python微信跳一跳系列之色块轮廓定位棋盘
2018/02/26 Python
python中for用来遍历range函数的方法
2018/06/08 Python
django缓存配置的几种方法详解
2018/07/16 Python
详解Python的三种可变参数
2019/05/08 Python
python3常用的数据清洗方法(小结)
2019/10/31 Python
Python tkinter模版代码实例
2020/02/05 Python
python加密解密库cryptography使用openSSL生成的密匙加密解密
2020/02/11 Python
基于pandas向csv添加新的行和列
2020/05/25 Python
化学专业毕业生自荐信
2013/11/15 职场文书
学生党员思想汇报
2013/12/28 职场文书
学习十八届三中全会精神实施方案
2014/02/17 职场文书
合作协议书格式
2014/08/19 职场文书