jQuery源码阅读3— bulidFragment( )

683 查看

jQuery的buildFragment函数,主要是将传入的HTML代码用document.createDocumentFragment转变成文档碎片,具体细节如下图:

图片来源于jQuery技术内幕:

jQuery.buildFragment = function( args, nodes, scripts ) {
//args:准备转换为DOM结构的THML代码
//nodes:数组,含有DOM元素或者jquery对象,用于修正创建文档片段DocumentFragment文档对象
//scripts:存放HTML代码的script元素
var fragment, cacheable, cacheresults, doc,
first = args[ 0 ];

if ( nodes && nodes[0] ) {
    doc = nodes[0].ownerDocument || nodes[0];
    //ownerDocument取节点所在的整个DOM树
    //修正nodes里面的参数
}

if ( !doc.createDocumentFragment ) {
    doc = document;
    //如果不存在createDocumentFragment则用DOM1的方法
}

if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&
    first.charAt(0) === "<" && !rnocache.test( first ) &&
    (jQuery.support.checkClone || !rchecked.test( first )) &&
    (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
    // rnocache = /<(?:script|object|embed|option|style)/i,
    // rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
    // rnoshimcache = new RegExp("<(?:" + nodeNames + ")", "i"),
    // 判断是否符合缓存
    // 1、 args.length === 1  : args长度大于1,且第一个元素是字符串
    // 2、 first.length < 512 : 长度小于512字节,太大就不缓存了
    // 3、 doc === document   : doc是当前文档对象,不缓存其他框架(iframe)
    // 4、 first.charAt(0) === "<" : HTML代码以左尖括号开头,即只缓存DOM元素,不缓存文本节点
    // 5、不能含有<script>、<object>、<embed>、<option>、<style>
    // 6、jQuery.support.html5Clone || !rnoshimcache.test( first )  , 可以复制HTML5元素或者HTML代码中不含有HTML标签

    cacheable = true;
    // 在使用转换后的DOM元素时,如果cacheable为true,则必须先复制一份再使用,否则可以直接使用

    cacheresults = jQuery.fragments[ first ];
    //尝试从缓存读数据
    if ( cacheresults && cacheresults !== 1 ) {
        fragment = cacheresults;
    }
}

if ( !fragment ) {
    fragment = doc.createDocumentFragment();
    jQuery.clean( args, doc, fragment, scripts );
    // jQuery.clean可以将HTML代码转换为DOM节点
}

if ( cacheable ) {
    jQuery.fragments[ first ] = cacheresults ? fragment : 1;
    // 如果符合缓存,则把转换后的DOM元素放入缓存对象jQuery.fragments中
}

return { fragment: fragment, cacheable: cacheable };

};