最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue中fragment.js使用方法詳解

 更新時間:2017年03月09日 16:01:29   作者:duiel  
這篇文章主要為大家詳細介紹了Vue中fragment.js的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下

 大部分內(nèi)容源自 jQuery,當(dāng)然,同時也參考了 component/domify ,如果有興趣去這翻閱原始的代碼,可以到 jQuery 中查找 wrapMap;至于 domify,直接到 github 搜索即可,相關(guān)項目類容很少,直接看 index.js 就行了。

createDocumentFragment

如果要在一個節(jié)點上一次性插入多個元素怎么辦,比如說一次插入 10000 個節(jié)點?

最簡單粗暴的方式就是:

var parent = document.getElementById('parent');
for(var i = 0; i < 10000; i++) {
 var child = document.createElement('div');
 var text = document.createTextNode('' + i);
 child.appendChild(text);
 parent.appendChild(child);
}

不過眾所周知的原因,對 DOM 反復(fù)操作會導(dǎo)致頁面重繪、回流,效率非常低,而且頁面可能會被卡死,這段代碼基本是沒人用的。

如果分段來進行 DOM 操作呢,這樣就能避免卡死頁面了,js 忍者秘籍里面提到過可以用 setTimeout 來改進:

var i = 0, max = 10000;
setTimeout(function addNodes() {
 for(var step = i + 500; i < step; i++) {
  var child = document.createElement('div');
  child.appendChild(document.createTextNode('' + i));
  div.appendChild(child);
 }
 if(i < max) {
  setTimeout(addNodes, 0);
 }
}, 0);

當(dāng)然,更多能想到的方式應(yīng)該是,在內(nèi)存中直接操作節(jié)點,所有節(jié)點都湊在一起之后再跟 DOM 樹進行交互,把所有節(jié)點都串在一個 div 上,然后再把 div 掛到 DOM 樹上:

var parent = document.getElementById('parent');
var div = document.createElement('div');
for(var i = 0; i < 10000; i++) {
 var child = document.createElement('div');
 var text = document.createTextNode('' + i);
 child.appendChild(text);
 div.appendChild(child);
}
parent.appendChild(div);

如上,只跟 DOM 樹交互一次,性能方面肯定是大有改善的,不過額外插入了一個 div,如果說不是跟div之類的節(jié)點進行交互呢,比如在 table 中插入 th、td?

這時候,createDocumentFragment 就該出馬了,翻譯過來叫“文檔片段”,按MDN的描述

DocumentFragments 是一些 DOM 節(jié)點。它們不是 DOM 樹的一部分。通常的使用場景是創(chuàng)建一個文檔片段,然后將創(chuàng)建的 DOM 元素插入到文檔片段中,最后把文檔片段插入到 DOM 樹中。在 DOM 樹中,文檔片段會被替換為它所有的子元素。

因為文檔片段存在與內(nèi)存中,并不在 DOM 樹中,所以將子元素插入到文檔片段時不會引起頁面回流(對元素位置和幾何上的計算)。因此,使用文檔片段 document fragments 通常會起到優(yōu)化性能的作用。

簡單來說,就是上面一個例子的不需要 div 中轉(zhuǎn)版本,插入的時候,直接用其子元素替換其本身,非常完美。

雖然說,“好用的都不通用”(特別是針對某公司瀏覽器),不過這個好用的東西,甚至連 IE6 都支持。

具體代碼大概就長這樣:

var parent = document.getElementById('parent');
var frag = document.createDocumentFragment();
for(var i = 0; i < 10000; i++) {
 var child = document.createElement('div');
 var text = document.createTextNode('' + i);
 child.appendChild(text);
 frag.appendChild(child);
}
parent.appendChild(frag);

具體性能方面的測試,有興趣的可以把所有代碼都跑一遍。

innerHTML

把一長串字符串轉(zhuǎn)換為對應(yīng)的 DOM 節(jié)點,正常而言,首先想到的肯定是 innerHTML。大概流程就是,先創(chuàng)建一個 div 節(jié)點,然后 div.innerHTML = str,根據(jù)需要把 div 的 children 取出來放到該放的地方去,div 本身給扔了。

如果想單獨生成一個 th 節(jié)點呢?

試試上面的流程:

var div = document.createElement('div');
div.innerHTML = '<th>xxx</th>';
console.log(div);

實際輸出是(chrome 下):

<div>xxx</div>

并沒有得到想要的:

<div><th>xxx</th></div>

對于這樣的結(jié)果是可以理解的,畢竟一個 th 放到 div 里面,怎么看都不對,直接把外圍的標(biāo)簽去掉,內(nèi)容扔到 div 里面也是相當(dāng)智能的。

不過架不住,有時候就是要獲取一個 th 節(jié)點。

其實也好辦,寫全了不就得了:

var node = document.createElement('div');
node.innerHTML = '<table><tbody><tr><th>xxx</th></tr></tbody></table>';
// 把外面的幾層皮扒掉就是想要的 th 了
var depth = 3;
while(depth--) {
 node = node.lastChild;
 }
console.log(node.firstChild);

可以看出,結(jié)果正是所想要的。

fragment.js

// 需要單獨處理的一些特殊節(jié)點
var map = {
 legend : [1, '<fieldset>', '</fieldset>'],
 tr : [2, '<table><tbody>', '</tbody></table>'],
 col : [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],

 _default : [0, '', '']
};
map.td = map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
map.option = map.optgroup = [1, '<select multiple="multiple">', '</select>'];
map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '<table>', '</table>']
map.text = map.circle = map.ellipse = map.line = map.path = map.polygon = map.polyline = map.rect = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">','</svg>'];

var TAG_RE = /<([\w:]+)/;

module.exports = function(templateString) {
 var frag = document.createDocumentFragment(),
  m = TAG_RE.exec(templateString);
 // 單純字符串的情況
 if(!m) {
  frag.appendChild(document.createTextNode(templateString);
  return frag;
 }

 var tag = m[1],
  wrap = map[tag] || map._default,
  depth = wrap[0],
  prefix = wrap[1],
  suffix = wrap[2],
  node = document.createElement('div');
 // 拼接節(jié)點字符串
 node.innerHTML = prefix + templateString.trim() + suffix;
 // 去除外包裹層,只留字符串轉(zhuǎn)化的節(jié)點
 while(depth--) node = node.lastChild;
 // 只有一個節(jié)點的情況
 if(node.firstChild === node.lastChild) { 
  frag.appendChild(node.firstChild);
  return frag;
 }
 // 多個節(jié)點,依序添加到 frag
 var child;
 while(child = node.firstChild) {
  frag.appendChild(child);
 }
 return frag;
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

黄浦区| 望奎县| 临猗县| 裕民县| 东平县| 安丘市| 邵东县| 凤凰县| 新野县| 巴彦淖尔市| 柳河县| 英德市| 贵南县| 安康市| 左贡县| 青阳县| 南木林县| 枝江市| 高平市| 竹溪县| 化德县| 玉屏| 阳信县| 南部县| 大化| 海阳市| 株洲县| 巫溪县| 麻江县| 清涧县| 江口县| 扶风县| 博乐市| 崇阳县| 炎陵县| 宜良县| 龙川县| 深圳市| 盐津县| 苍溪县| 莱西市|