JavaScript頁面迴流與重繪
目錄
- 1.DOMAPI
- 1.1獲取元素相關結點API
- 1.2增加節點API
- 2.迴流與重繪
- 2.1的書寫順序影響
- 2.2節點渲染優化
1.DOMAPI
1.1獲取元素相關結點API
<body> <div class="item"> <h3 class="title">123</h3> <p class="des">456</p> <p class="price">789</p> </div> <script> var oItem = document.querySelector(".item"); var oTitle = oItem.querySelector("h3"); var itemChild = oItem.children;//獲取當前物件的所有子元素,並且以集合的形式返回 console.log(itemChild); console.log(oItem.childNodes);//獲取元素內的節點列表,注意,換行符也會被當做是一個文字節點 console.log(oItem.firstChild);//獲取元素第一個子(節點:標籤和文字) console.log(oItem.firstElementChild);//獲取元素第一個JeksZi子元素(只指代標籤 不包括文字節點) console.log(oItem.lastChild);//獲取元素最後一個子(節點:標籤和文字) console.log(oItem.lastElementChild);//獲取元素最後一個子元素(只指代標籤 不包括文字節點) //Node節點 Element元素 console.log(oTitle.parentElement);//獲取元素父元素 console.log(oTitle.parentNode);//也是獲取父元素 console.log(oTitle.nextElementSibling);//下一個兄弟元素 console.log(oTitle.nextSibling);//下一個兄弟節點(包含文字節點) console.log(oTitle.previousElementSibling);//上一個兄弟元素 console.log(oTitle.previousSibling);//上一個兄弟節點(包含文字節點) </script> </body>
1.2增加節點API
<script> var oWrap = document.createElement("div"); //引數是tagName,也就是標籤名稱 oWrap.className = "wrap";//新增類名 oWrap.innerText = "文字";//新增一些文字 oWrap.style.fontSize = "30px";//設定字型大小 oWrap.style.color = "red";//設定顏色 //向body裡新增標籤 document.body.appendChild(oWrap); /http://www.cppcns.com/向新增的div標籤裡再www.cppcns.com新增一個p標籤 var oP = document.createElement("p"); oP.innerText = "我是p標籤"; oWrap.appendChild(oP); //用innerHTML來新增節點 var elementStr = '<div class="erao"><p style="color: red; font-size: 30px;">我是p是wrap的子元素</p></div>'; document.body.innerHTML = elementStr; </script>
2.迴流與重繪
2.1CSS的書寫順序影響
示例:
span { width: 200px; height: 200px; margin: 10px; border: 2px solid red; background-color: #368; }
如上的css程式碼,在HTML頁面中span標籤不會被渲染出來,這是因為span標籤是行級元素,不能設定width
和height
值,如果我們在最下面寫一行position: absolute
;,這就會導致瀏覽器切換計算模式。
瀏覽器在讀css程式碼時是從上而下一行一行程式碼讀的,在沒有讀到這行程式碼時瀏覽器先是用的行級元素的計算模式來閱讀這段css程式碼,當讀到position: absolute;
這行程式碼時
瀏覽器隱式的將span的display
展示模式更改為block,自然也將計算模式切換成塊級元素的計算模式,然後再從頭讀這段css程式碼,渲染。
2.2節點渲染優化
一個html頁面是一個整體,當這個整體中的某一個部分發生改變,那麼這個頁面整體會重新進行渲染,而如果我們採用新增標籤的方式,每次新增一個標籤,就會讓每一次頁面都重新渲染,效能急劇下降
解決方法是:使用Fragment
臨時容器
示例:
drawDom(3000,'div'); function drawDom(num,tagName) { var vDom; for (var i = 0; i < num; i++) { vDom = document.createElement(tagName); document.body.appendChild(vDom); //重複N次 每次渲染一個標籤 } }
如上述程式碼,當我們一個一個渲染3000個標籤的時候,在本地的頁面開啟都需要一秒多,如果是線上的,那效能更加差
所以我們要使用Fragement
臨時容器,如果說頁面渲染相當於貨架上的商品,那麼appendChild
方法就相當於每一次從工廠生產商品立刻送到商店擺上貨架,每一次都需要重新編排商品。
而使用Fragement
時,就相當於在工廠和貨架之間放置了一個大箱子,工廠生產出賴商品後先將商品放置在Fragment
裡,當需要的商品數量生產完後,再將Fragement這個大箱子直接提到商店,將裡面的商品一次性擺上貨架,這時就只需要編排一次商品,大大的提升了渲染效能。
修改後的程式碼:
drawDom(3000,tagName) {
var vDom;
var fragment = document.createDocumentFragment();//文件片段
for (var i = 0; i < num; i++) {
vDom = document.createElement(tagName); //
fragment.appendChild(vDom); //放到臨時容器JeksZifragment裡
}
document.body.appendChild(fragment); //一次渲染渲染N個
}
這裡要注意innerHTML
也會有同樣的問題,解決的方式就是不要用innerHTML來每一次改變,而是以一個字串來進行改變,等所有的改變結束後再直接賦值給innerHTML,也是能大大提升效能的
示例:
drawHtml(3000,'div'); function drawHtml(num,tagName) { var eleStr = ''; for (var i = 0; i < num; i++) { eleStr += '<' + tagName + '></' + tagName + '>'; } document.body.innerHTML = eleStr; }
到此這篇關於頁面迴流與重繪的文章就介紹到這了,更多相關Script頁面迴流與重繪內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!