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