• jQuery 3.0的buildFragment


    在 jQuery3.0中,buildFragment 是一个私有函数,用来构建一个包含子节点 fragment 对象。这个 fragment 在 DOM1 中就已经有了,所有浏览器都支持。当频繁操作(添加、插入) DOM 时使用该方法可以提高性能,John resig 做过一个测试及一篇博客

    jQuery3.0 中 buildFragment 只在 domManip 和 jQuery.parseHTML 中使用,domManip 则被 DOM 操作如 append、prepend、before、after 等方法的所依赖。如下图

    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;
    }
    

    该方法主要执行步骤

    1. 通过第二个参数 content 创建 fragment
    2. 通过第一个参数 elems 构建 nodes ,将 elems 内元素转成 DOM 元素存放于数组 nodes 中
    3. 将 nodes 里元素循环放入添加到文档碎片 fragment 上
    4. 返回 fragment

    重点在第 2 步,构建 nodes,有 3 种情形

    1. elem 是 DOM 元素(根据nodeType判断),直接放入 nodes 数组中
    2. elem 是字符串且不是 HTML tag,创建文本节点对象(textNode),放入 nodes 数组中
    3. elem 是字符串且是 HTML tag,将其转成 DOM 元素,放入 nodes 数组中

    如图示

    后面的两个参数需要注意下

    1. 最后两个参数 selection 和 ignored 只在 replaceWith 方法里使用。需要了解的是 replaceWith 只做节点替换,不会替换先前元素的所有数据(Data),比如绑定事件,$.data 都不会被新元素拥有。

    2. scripts 参数只在 jQuery.parseHTML 方法里使用(domManip里传false),当 jQuery.parseHTML 的第三个参数 keepScripts 为 false 时将删除节点里所有的 script tag

    buildFragment 在 jQuery 各个版本中的演变

    1. 1.0.x ~ 1.3.x 中没有 buildFragment 函数,即没有抽取出该函数为 domManip 服务
    2. 1.4.x 中首次引入 buildFragment ,当时是挂在 jQuery 上的静态方法,有三个参数 args, nodes, scripts。一直到2.x.x 依然是公开可以访问的
    3. 3.x.x 开始 buildFragment 变成了一个私有函数,只能在 jQuery 代码内部访问,客户端程序员无法访问
  • 相关阅读:
    FFmpeg在Linux下搭建 ***
    网络互联参考模型
    Linux的SOCKET编程详解
    [Python爬虫] 之四:Selenium 抓取微博数据
    [Python爬虫] 之三:Selenium 调用IEDriverServer 抓取数据
    [Python爬虫] 之二:Selenium 调用IEDriverServer打开IE浏览器安装配置
    Windows MongoDB安装配置
    windows10下部署IIS10+Django web服务
    [Python爬虫] 之一 : Selenium+Phantomjs动态获取网站数据信息
    windows10 phantomjs 安装和使用
  • 原文地址:https://www.cnblogs.com/snandy/p/5760742.html
Copyright © 2020-2023  润新知