<p><code></p> <p><a href="http://www.js-code.com/tag/jquery" title="jQuery" target="_blank">jQuery</a>的buildFragment函数,主要是将传入的<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a>代码用document.createDocumentFragment转变成文档碎片,具体细节如下图:</p> <p>图片来源于<a href="http://www.js-code.com/tag/jquery" title="jQuery" target="_blank">jQuery</a>技术内幕:</p> <p><span class="img-wrap"><img data-src="/img/bVm3ww" src="/img/bVm3ww" alt="clipboard.png" style="cursor: pointer; display: inline;"></span></p> <p><a href="http://www.js-code.com/tag/jquery" title="浏览关于“jQuery”的文章" target="_blank" class="tag_link">jQuery</a>.buildFragment = function( args, <a href="http://www.js-code.com/tag/node" title="node" target="_blank">node</a>s, scripts ) {<br /> //args:准备转换为<a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a>结构的THML代码<br /> //<a href="http://www.js-code.com/tag/node" title="node" target="_blank">node</a>s:<a href="http://www.js-code.com/tag/%e6%95%b0%e7%bb%84" title="数组" target="_blank">数组</a>,含有<a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a>元素或者jquery对象,用于修正创建文档片段DocumentFragment文档对象<br /> //scripts:存放<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a>代码的script元素<br /> var fragment, cacheable, cacheresults, doc,<br /> first = args[ 0 ];</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="if ( <a href="http://www.js-code.com/tag/node" title="浏览关于“node”的文章" target="_blank" class="tag_link">node</a>s &amp;&amp; nodes[0] ) {<br /> doc = nodes[0].ownerDocument || nodes[0];<br /> //ownerDocument取节点所在的整个<a href="http://www.js-code.com/tag/dom" title="浏览关于“DOM”的文章" target="_blank" class="tag_link">DOM</a>树<br /> //修正nodes里面的参数<br /> }</p> <p>if ( !doc.createDocumentFragment ) {<br /> doc = document;<br /> //如果不存在createDocumentFragment则用DOM1的方法<br /> }</p> <p>if ( args.length === 1 &amp;&amp; typeof first === &quot;string&quot; &amp;&amp; first.length < 512 &amp;&amp; doc === document &amp;&amp; first.charAt(0) === &quot;<&quot; &amp;&amp; !rnocache.test( first ) &amp;&amp; (jQuery.support.checkClone || !rchecked.test( first )) &amp;&amp; (jQuery.support.<a href="http://www.js-code.com/tag/html5" title="html5" target="_blank">html5</a>Clone || !rnoshimcache.test( first )) ) {<br /> // rnocache = /<(?:script|object|embed|option|style)/i, // rchecked = /checkeds*(?:[^=]|=s*.checked.)/i, // rnoshimcache = new RegExp(&quot;<(?:&quot; + nodeNames + &quot;)&quot;, &quot;i&quot;), // 判断是否符合缓存 // 1、 args.length === 1 : args长度大于1,且第一个元素是字符串 // 2、 first.length < 512 : 长度小于512字节,太大就不缓存了 // 3、 doc === document : doc是当前文档对象,不缓存其他框架(iframe) // 4、 first.charAt(0) === &quot;<&quot; : <a href="http://www.js-code.com/tag/html" title="浏览关于“HTML”的文章" target="_blank" class="tag_link">HTML</a>代码以左尖括号开头,即只缓存DOM元素,不缓存文本节点<br /> // 5、不能含有<script>、<object>、<embed>、<option>、</p> <style> // 6、jQuery.support.html5Clone || !rnoshimcache.test( first ) , 可以复制HTML5元素或者HTML代码中不含有HTML标签</p> <p> cacheable = true;<br /> // 在使用转换后的DOM元素时,如果cacheable为true,则必须先复制一份再使用,否则可以直接使用</p> <p> cacheresults = jQuery.fragments[ first ];<br /> //尝试从缓存读数据<br /> if ( cacheresults &amp;&amp; cacheresults !== 1 ) {<br /> fragment = cacheresults;<br /> }<br /> }</p> <p>if ( !fragment ) {<br /> fragment = doc.createDocumentFragment();<br /> jQuery.clean( args, doc, fragment, scripts );<br /> // jQuery.clean可以将HTML代码转换为DOM节点<br /> }</p> <p>if ( cacheable ) {<br /> jQuery.fragments[ first ] = cacheresults ? fragment : 1;<br /> // 如果符合缓存,则把转换后的DOM元素放入缓存对象jQuery.fragments中<br /> }</p> <p>return { fragment: fragment, cacheable: cacheable };<br /> " title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs typescript"><code><span class="hljs-keyword">if</span> ( nodes &amp;&amp; nodes[<span class="hljs-number">0</span>] ) { doc = nodes[<span class="hljs-number">0</span>].ownerDocument || nodes[<span class="hljs-number">0</span>]; <span class="hljs-comment">//ownerDocument取节点所在的整个DOM树</span> <span class="hljs-comment">//修正nodes里面的参数</span> } <span class="hljs-keyword">if</span> ( !doc.createDocumentFragment ) { doc = <span class="hljs-built_in">document</span>; <span class="hljs-comment">//如果不存在createDocumentFragment则用DOM1的方法</span> } <span class="hljs-keyword">if</span> ( args.length === <span class="hljs-number">1</span> &amp;&amp; <span class="hljs-keyword">typeof</span> first === <span class="hljs-string">"string"</span> &amp;&amp; first.length &lt; <span class="hljs-number">512</span> &amp;&amp; doc === <span class="hljs-built_in">document</span> &amp;&amp; first.charAt(<span class="hljs-number">0</span>) === <span class="hljs-string">"&lt;"</span> &amp;&amp; !rnocache.test( first ) &amp;&amp; (jQuery.support.checkClone || !rchecked.test( first )) &amp;&amp; (jQuery.support.<a href="http://www.js-code.com/tag/html5" title="浏览关于“html5”的文章" target="_blank" class="tag_link">html5</a>Clone || !rnoshimcache.test( first )) ) { <span class="hljs-comment">// rnocache = /&lt;(?:script|object|embed|option|style)/i,</span> <span class="hljs-comment">// rchecked = /checkeds*(?:[^=]|=s*.checked.)/i,</span> <span class="hljs-comment">// rnoshimcache = new RegExp("&lt;(?:" + nodeNames + ")", "i"),</span> <span class="hljs-comment">// 判断是否符合缓存</span> <span class="hljs-comment">// 1、 args.length === 1 : args长度大于1,且第一个元素是字符串</span> <span class="hljs-comment">// 2、 first.length &lt; 512 : 长度小于512字节,太大就不缓存了</span> <span class="hljs-comment">// 3、 doc === document : doc是当前文档对象,不缓存其他框架(iframe)</span> <span class="hljs-comment">// 4、 first.charAt(0) === "&lt;" : HTML代码以左尖括号开头,即只缓存DOM元素,不缓存文本节点</span> <span class="hljs-comment">// 5、不能含有&lt;script&gt;、&lt;object&gt;、&lt;embed&gt;、&lt;option&gt;、&lt;style&gt;</span> <span class="hljs-comment">// 6、jQuery.support.html5Clone || !rnoshimcache.test( first ) , 可以复制HTML5元素或者HTML代码中不含有HTML标签</span> cacheable = <span class="hljs-literal">true</span>; <span class="hljs-comment">// 在使用转换后的DOM元素时,如果cacheable为true,则必须先复制一份再使用,否则可以直接使用</span> cacheresults = jQuery.fragments[ first ]; <span class="hljs-comment">//尝试从缓存读数据</span> <span class="hljs-keyword">if</span> ( cacheresults &amp;&amp; cacheresults !== <span class="hljs-number">1</span> ) { fragment = cacheresults; } } <span class="hljs-keyword">if</span> ( !fragment ) { fragment = doc.createDocumentFragment(); jQuery.clean( args, doc, fragment, scripts ); <span class="hljs-comment">// jQuery.clean可以将HTML代码转换为DOM节点</span> } <span class="hljs-keyword">if</span> ( cacheable ) { jQuery.fragments[ first ] = cacheresults ? fragment : <span class="hljs-number">1</span>; <span class="hljs-comment">// 如果符合缓存,则把转换后的DOM元素放入缓存对象jQuery.fragments中</span> } <span class="hljs-keyword">return</span> { fragment: fragment, cacheable: cacheable }; </code></pre> <p>};</p> <p></code></p>

本文固定链接: http://www.js-code.com/jquery/jquery_39916.html