jQuery3.0中的buildFragment私有函数详解

时间: 作者:活没

  

[jquery3,0,buildfragment]jQuery3.0中的buildFragment私有函数详解

  

时隔 3 个月,jQuery 团队终于发布了 3.0 Alpha 版本。有两个版本 jQuery compat 3.0 和 jQuery 3.0。

  

  

jQuery compat 3.0 对应之前的 1.x, 兼容更多的浏览器,对于IE支持到 8.0 版本  

  

jQuery 3.0 对应之前的 2.x,关注更新的浏览器,对于IE支持到 9.0 版本  

  

此外, 3.0还增加了对 Yandex 浏览器的支持,一款来自俄罗斯的浏览器。

  

  

下面看下jQuery3.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;  }
  
  

该方法主要执行步骤  

  

通过第二个参数 content 创建 fragment  

  

通过第一个参数 elems 构建 nodes ,将 elems 内元素转成 DOM 元素存放于数组 nodes 中  

  

将 nodes 里元素循环放入添加到文档碎片 fragment 上  

  

返回 fragment  
  

  

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

  

elem 是 DOM 元素(根据nodeType判断),直接放入 nodes 数组中  

  

elem 是字符串且不是 HTML tag,创建文本节点对象(textNode),放入 nodes 数组中  

  

elem 是字符串且是 HTML tag,将其转成 DOM 元素,放入 nodes 数组中  
  

  

如图示  

  

  

  

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

  

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

推荐图片Related

相关文章Related

查看更多热门新闻


首页 | js代码 | jQuery特效 | 其他代码 | 关于我们

Copyright © 2010-2019 菲娱国际平台 版权所有

系统要求:本站自适应各终端浏览器分辨率

请使用Google、Firefox、IE9、百度浏览器登录网站

网站地图 | RSS订阅 | 菲娱国际平台