于 jQuery3.0中,buildFragment 是一个私家函数,用来构建一个富含子节点
fragment 对象。这个
fragment 在
DOM1 中尽管已经发生矣,所有浏览器都支持。当数操作(添加、插入) DOM
时使用该措施可增进性,John resig
做过一个测试及一篇博客。

 

jQuery3.0 中 buildFragment 只在 domManip 和 jQuery.parseHTML
中以,domManip 则叫 DOM 操作而 append、prepend、before、after
等艺术的所因。如下图

jQuery 1

 

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 数组中

 

如图示

jQuery 2

 

末尾的个别单参数需要注意下

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

jQuery 3

 

  1. scripts 参数就以 jQuery.parseHTML 方法里应用(domManip里传false),当
    jQuery.parseHTML 的老三只参数 keepScripts 为 false 时拿去除节点里装有的
    script tag

jQuery 4

 

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
    代码内部访问,客户端程序员无法访问

相关文章

网站地图xml地图