JavaScript頁面回流與重繪
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);//獲取元素內的節(jié)點列表,注意,換行符也會被當做是一個文本節(jié)點
?? ??? ?console.log(oItem.firstChild);//獲取元素第一個子(節(jié)點:標簽和文本)
?? ??? ?console.log(oItem.firstElementChild);//獲取元素第一個子元素(只指代標簽 ?不包括文本節(jié)點)
?? ??? ?console.log(oItem.lastChild);//獲取元素最后一個子(節(jié)點:標簽和文本)
?? ??? ?console.log(oItem.lastElementChild);//獲取元素最后一個子元素(只指代標簽 ?不包括文本節(jié)點)
?? ??? ?//Node節(jié)點 ?Element元素
?? ??? ?console.log(oTitle.parentElement);//獲取元素父元素
?? ??? ?console.log(oTitle.parentNode);//也是獲取父元素
?? ??? ?console.log(oTitle.nextElementSibling);//下一個兄弟元素
?? ??? ?console.log(oTitle.nextSibling);//下一個兄弟節(jié)點(包含文本節(jié)點)
?? ??? ?console.log(oTitle.previousElementSibling);//上一個兄弟元素
?? ??? ?console.log(oTitle.previousSibling);//上一個兄弟節(jié)點(包含文本節(jié)點)
?? ?</script>
</body>1.2增加節(jié)點API
<script>
?? ?var oWrap = document.createElement("div");
?? ?//參數(shù)是tagName,也就是標簽名稱
?? ?oWrap.className = "wrap";//添加類名
?? ?oWrap.innerText = "文本";//添加一些文本
?? ?oWrap.style.fontSize = "30px";//設置字體大小
?? ?oWrap.style.color = "red";//設置顏色
?? ?//向body里添加標簽
?? ?document.body.appendChild(oWrap);
?? ?//向添加的div標簽里再添加一個p標簽
?? ?var oP = document.createElement("p");
?? ?oP.innerText = "我是p標簽";
?? ?oWrap.appendChild(oP);
?? ?//用innerHTML來添加節(jié)點
?? ?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節(jié)點渲染優(yōu)化
一個html頁面是一個整體,當這個整體中的某一個部分發(fā)生改變,那么這個頁面整體會重新進行渲染,而如果我們采用添加標簽的方式,每次添加一個標簽,就會讓每一次頁面都重新渲染,性能急劇下降
解決方法是:使用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里,當需要的商品數(shù)量生產完后,再將Fragement這個大箱子直接提到商店,將里面的商品一次性擺上貨架,這時就只需要編排一次商品,大大的提升了渲染性能。
修改后的代碼:
drawDom(3000, 'div');
? ? function drawDom(num, tagName) {
? ? ? var vDom;
? ? ? var fragment = document.createDocumentFragment();//文檔片段
? ? ? for (var i = 0; i < num; i++) {
? ? ? ? vDom = document.createElement(tagName); //
? ? ? ? fragment.appendChild(vDom); //放到臨時容器fragment里
? ? ? }
? ? ? 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;
}
到此這篇關于JavaScript頁面回流與重繪的文章就介紹到這了,更多相關JavaScript頁面回流與重繪內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
淺談JS對html標簽的屬性的干預以及對CSS樣式表屬性的干預
下面小編就為大家?guī)硪黄獪\談JS對html標簽的屬性的干預以及對CSS樣式表屬性的干預。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06
javascript中的Base64、UTF8編碼與解碼詳解
本文給大家介紹的是javascript中的Base64、UTF8編碼與解碼的函數(shù)源碼分享以及使用范例,十分實用,推薦給小伙伴們,希望大家能夠喜歡。2015-03-03

