中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue中fragment.js使用方法詳解

發布時間:2020-08-23 19:53:23 來源:腳本之家 閱讀:425 作者:duiel 欄目:web開發

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

createDocumentFragment

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

最簡單粗暴的方式就是:

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 反復操作會導致頁面重繪、回流,效率非常低,而且頁面可能會被卡死,這段代碼基本是沒人用的。

如果分段來進行 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);

當然,更多能想到的方式應該是,在內存中直接操作節點,所有節點都湊在一起之后再跟 DOM 樹進行交互,把所有節點都串在一個 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之類的節點進行交互呢,比如在 table 中插入 th、td?

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

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

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

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

雖然說,“好用的都不通用”(特別是針對某公司瀏覽器),不過這個好用的東西,甚至連 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

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

如果想單獨生成一個 th 節點呢?

試試上面的流程:

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

實際輸出是(chrome 下):

<div>xxx</div>

并沒有得到想要的:

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

對于這樣的結果是可以理解的,畢竟一個 th 放到 div 里面,怎么看都不對,直接把外圍的標簽去掉,內容扔到 div 里面也是相當智能的。

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

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

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

可以看出,結果正是所想要的。

fragment.js

// 需要單獨處理的一些特殊節點
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');
 // 拼接節點字符串
 node.innerHTML = prefix + templateString.trim() + suffix;
 // 去除外包裹層,只留字符串轉化的節點
 while(depth--) node = node.lastChild;
 // 只有一個節點的情況
 if(node.firstChild === node.lastChild) { 
  frag.appendChild(node.firstChild);
  return frag;
 }
 // 多個節點,依序添加到 frag
 var child;
 while(child = node.firstChild) {
  frag.appendChild(child);
 }
 return frag;
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

铜鼓县| 英德市| 资源县| 长寿区| 宁陕县| 新民市| 双鸭山市| 尉氏县| 南投市| 杭州市| 呼伦贝尔市| 东光县| 天镇县| 北票市| 基隆市| 阿瓦提县| 西藏| 西平县| 英超| 襄樊市| 夏河县| 登封市| 宜宾市| 镇沅| 哈尔滨市| 天等县| 金堂县| 麻阳| 固安县| 浙江省| 肇州县| 婺源县| 上饶县| 瑞昌市| 铜山县| 海安县| 延安市| 桃园县| 信宜市| 兴和县| 太保市|