国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Vue中fragment.js使用方法詳解

2019-11-19 17:12:29
字體:
來源:轉載
供稿:網友

 大部分內容源自 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;}

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 贵定县| 尼勒克县| 安庆市| 永善县| 凤凰县| 穆棱市| 芜湖市| 久治县| 大余县| 友谊县| 泸西县| 巨鹿县| 赫章县| 高要市| 阿巴嘎旗| 崇义县| 盘锦市| 枣强县| 连山| 陕西省| 肇庆市| 河津市| 沂水县| 印江| 桃江县| 吴桥县| 禹州市| 湘西| 昭苏县| 鄂托克旗| 桂阳县| 庐江县| 泰州市| 绥滨县| 佛学| 普格县| 曲松县| 永寿县| 延川县| 正安县| 永德县|