DOM
document object model 文檔對象模型,它裏面提供了一系列的屬性和方法,能夠讓JS操作頁面中的元素。
一個HTML有頁面的組成如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM是什麼</title>
</head>
<body>
<div></div>
</body>
</html>
其中出現了很多的標籤,這些標籤也被稱爲節點(Node),一個頁面可以看做有很多的節點組成的,包括了常見的元素標籤、文本、註釋、空格、回車、換行符……都是節點。
獲取dom8個元素方法
- document.getElementById(‘id名’)
- document.getElementsByTagName(‘標籤名’)
- document.getElementsByClassName(‘類名’)(IE6-8下兼容)
- document.getElementsByName(‘屬性值’)
- document.documentElement//html元素
- document.body//body元素
- document.querySelector(“一個css選擇器”)
- document.querySelectorAll(“多個css選擇器”)
節點的7個關係屬性:
- childNodes:獲取的是元素的所有子節點,包括註釋、文字、標籤、回車、空格。
- children:獲取所有的標籤節點。(在ie6-8下獲取的值不準確會把註釋節點當作元素節點來獲取。)
- parentNode:獲取元素的父親節點。
- previousSibling:上一個哥哥節點。
- nextSibLing:下一個弟弟節點。
- firstChild:第一個子節點。
- lastChild:最後一個子節點。
可以將節點分爲以下4中類型
4個類型 | nodeType | nodeName | nodeValue |
---|---|---|---|
元素節點 | 1 | 大寫的標籤名 | null |
文本節點 | 3 | #text | 文字的內容 |
註釋節點 | 8 | #comment | 註釋的內容 |
document | 9 | #document | null |
常用的操作dom元素9個方法
容器.appendChild(我們要添加的元素) 把我們創建的標籤插到指定的容器(末尾)
oldVal.insertBefore(newVal,oldVal) 把一個元素添加另一個元素的前面
oldVal.replaceChild(newVal,oldVal) 一個元素把另一個元素替掉
元素.cloneNode() 把元素克隆一份 true(深度克隆) false
document.body.removeChild(我們要移除的元素)
setAttribute 設置元素的屬性名 (會在html結構中體現出來)
getAttribute 獲取元素的屬性名
removeAttribute 移除元素的屬性名
js中的盒子模型
通過一系列的屬性來獲取當前盒子的相關樣式。 盒子模型中的,width和height指的是內容的寬高
client(可視)系列
clientWidth
=width+padding(left+right)
clientHeight
=height(不設置height就是指的是內容的高度)+padding(top+bottom)
clientLeft
:左邊框高度
clientTop
:上邊框高度
沒有右邊框和和下邊框
這四個屬性和內容是否溢出沒有關係,因爲client使可視區域,溢出的內容不在可視區域內,我們可以設置overflow:hidden來隱藏溢出的內容。
//獲取當前頁面的可視區域(一屏幕)的寬度和高度(和頁面的內容是否溢出沒有關係),部分瀏覽器不識別用document.documentElement來操作瀏覽器的一些盒子模型的屬性,我們需要使用document.body來操作,所以需要寫兩套。
// document.documentElement.clientWidth||document.body.clientWidth
// document.documentElement.clientHeight||document.body.clientHeight
3、offsetWidth / offsetHeight:在clientWidth&clientHeight的基礎上加上邊框即可
獲取HTML頁面的真實寬高(包含溢出的內容) ‘約等於的值’
- document.documentElement.scrollWidth||document.body.scrollWidth
- document.documentElement.scrollHeight||document.body.scrollHeight
以上的JS屬性都是在特定的情況下使用(他們獲取的是複合值),如果想獲取元素具體某一個樣式屬性的值,上述的屬性就不合適了
獲取元素具體的css樣式
1、元素.style.樣式屬性
獲取元素寫在行內上的樣式屬性,重點記住只能獲取寫在行內的樣式,如果寫在樣式表中這個操作是無法獲取到的
2、getComputedStyle和currentStyle
獲取當前元素的所有經過瀏覽器計算的樣式
瀏覽器計算過的樣式:只要當前元素能在頁面中展示,那麼他的樣式都是經過瀏覽器計算的,不管你寫在哪,以及你寫不寫(有些樣式不寫,瀏覽器也有默認樣式)
getComputedStyle是window全局對象的一個屬性方法,但是在ie6-8下瀏覽器紅不存在這個屬性,低版本瀏覽器中我們使用currentStyle來獲取
[標準瀏覽器]
window.getComputedStyle([元素],[樣式僞類,一般都用NULL]) 獲取的結果是一個對象,存儲了所有經過計算的樣式
[元素].currentStyle 獲取的結果也是一個對象,存儲了所有經過計算的樣式
offsetLeft / offsetTop / offsetParent
獲取當前元素的 左偏移 / 上偏移 / 父級參照物
1、offsetParent:獲取當前元素的父級參照物
在默認的情況下,BODY中出現的所有元素的父級參照物都是BODY(因爲在同一個平面上),BODY本身的父級參照物是NULL
我們通過設置POSITION定位,可以讓元素脫離文檔流,從而改變元素的父級參照物(CSS中我們當前元素是相對於誰定位的,那麼JS中它的父級參照物就是誰)
2、offsetLeft和offsetTop:當前元素距離其父級參照物的左偏移和上偏移
在大部分瀏覽器中,這個距離是從當前元素的外邊框開始到父級參照物的內變框結束(不含父級元素的邊框)
IE8(純IE8,不是模擬器仿真),這個距離包含了父級參照物的邊框,偏移量=當前元素的外邊框到父級參照物的外邊框
scroll系列
scrollTop 和 scrollLeft:
當前容器(一般都是當前頁面)捲去的高度和寬度
學習的13個JS盒子模型屬性,只有這兩個屬性是‘可讀寫’的(可以獲取也可以設置),而其餘的11個屬性都是‘只讀’的
爲了兼容瀏覽器,我們設置或者獲取頁面的盒子模型屬性值的時候,都要寫兩套
有最小值,最小值是零,設置的值小於零也沒用
有最大值,真實頁面的高度document.documentElement.scrollHeight||document.body.scrollHeight - 可是窗口的高度document.documentElement.clientHeight||document.body.clientHeight
scrollWidth / scrollHeight
沒有內容溢出的情況下
- scrollWidth = clientWidth
- scrollHeight = clientHeight
有內容溢出的情況下
- scrollHeight = paddingTop + 真實內容的高度(包含溢出的內容)
- scrollWidth = paddingLeft + 真實內容的寬度(包含溢出的內容)
是否設置OVERFLOW:HIDDEN對獲取的結果是產生影響的,而且每個瀏覽器獲取的結果也還都不太一樣,所以我們的這兩個屬性值,在有內容溢出的情況下,我們獲取的值都是約等於的值
dom映射
通過dom方法獲取的是一個元素集合(類數組),這個集合仍然和頁面中的元素保持着聯繫,這個集合會隨着頁面中元素(節點)的增加而增加,減少而減少,即使把這個類數組轉換爲數組,每個元素都和頁面之間都存在着一定的聯繫。
dom迴流
元素的位置發生改變(增加元素,刪除元素,移動)引起迴流,讓整個頁面重新渲染一遍,從而造成性能浪費
在項目當中要儘可能的減少迴流發生下面以商品的上架時間排序爲例:
function sortGoods() {
//->排序
mallList.sort(function (cur, next) {
var curTime = cur.getAttribute('data-time');
var nextTime = next.getAttribute('data-time');
//"2017-03-15" VS "2017-02-08" =>把每一個時間的‘-’都去掉,然後比較數字的大小即可
curTime = curTime.replace(/-/g, '');
nextTime = nextTime.replace(/-/g, '');
return curTime - nextTime;
});
//->把當前最新的數據重新的增加到頁面中,以此更改頁面中內容的順序
var frg = document.createDocumentFragment();
//由於對頁面中的元素進行了排序操作會出發dom迴流,操作的次數越多,觸發的迴流也就越多,導致頁面加載性能差,在這裏我們創建了一個臨時變量frg
for (var i = 0; i < mallList.length; i++) {
frg.appendChild(mallList[i]);
}
//將排序之後的內容全部放在創建的文檔碎片中
mallItem.appendChild(frg);
//最後一次性的將內容添加也頁面當中,迴流也就只觸發一次,這樣就大大的提高了性能,
frg = null;
}
sortGoods();
dom重繪
元素樣式發生改變,就會把當前這個元素重新渲染一遍所以在以後項目中,能用重繪代替的就不用迴流,能用一次迴流就不用使用多次