js盒子模型常用屬性
1.js盒子模型
指的是通過js中提供的一系列的屬性和方法,獲取頁面中元素的樣式資訊值
例:
#box有很多自己的私有屬性:
HTMLDivElement.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype
var box = document.getElementById("box");
console.dir(box);
2.概念
2.1 內容的寬度和高度
我們設定的width/height這兩個樣式就是內容的寬和高;
● 如果沒有設定height值,容器的高度會根據裡面內容自適應,這樣獲取的值就是真實內容的高;
● 如果設定了固定的高度,不管內容是多還是少,其實我們內容的高度值的都是設定的那個值。
2.2 真實內容的寬度和高度
代指的是實際內容的寬高(和我們設定的height沒有必然的聯絡),如我設定高度為200,如果內容有溢位,那麼真實內容的高度是要把溢位內容的高度也加進來的。
3. js盒子模型常用屬性
3.1 client系列
3.1.1 clientWidth/clientHeight(只讀屬性)
● 內容的寬/高+左右/上下填充 (和內容是否溢位沒有關係)(即不包含border值)
● 如果設定了box-sizing:border-box;
3.1.2 clientLeft/clientTop (只讀屬性)
左/上邊框的寬度 (border[Left/Top]Width)
3.2 offset系列
<div id="outer"> <div id="inner"> <div id="center"></div> </div> </div> var outer = document.getElementById("outer"), inner = document.getElementById("inner"), center = document.getElementById("center");
3.2.1 offsetWidth/offsetHeight(只讀屬性)
clientWidth/clientHeight + 左右/上下邊框 (和內容是否溢位沒有關係)(包含border)
3.2.2 offsetParent
當前元素的父級參照物,在同一個平面中,最外層的元素是裡面所有元素的父級參照物(和html層級結構沒有必然的聯絡)
● 一般來說一個頁面中所有元素的父級參照物都是body
console.log(center.offsetParent); //body
console.log(inner.offsetParent); //body
console.log(outer.offsetParent); //body
console.log(document.body.offsetParent); //null
● 想要改變父級參照物需要通過position定位來進行改變:absolute,relative,fixed中任意一個值都可以把父級參照物進行修改
outer.style.position = "relative";
inner.style.position = "relative";
console.log(center.offsetParent); //inner
console.log(inner.offsetParent); //outer
console.log(outer.offsetParent); //body
3.2.3 offsetLeft/offsetTop(只讀屬性)
當前元素(外邊框)距離其父級參照物(內邊框)的偏移距離
console.log(center.offsetLeft); //距離body左偏移距離
console.log(inner.offsetLeft); //距離body左偏移距離
console.log(outer.offsetLeft); //距離body左偏移距離
outer.style.position = "relative";
inner.style.position = "relative";
console.log(center.offsetLeft); //距離inner左偏移距離
3.2.4 offset函式封裝
等同於jquery中的offset方法,實現獲取頁面中任意一個元素距離body的偏移(包含左偏移和上偏移),不管當前元素的父級參照物是誰
// 獲取的結果是一個物件{left:距離body的左偏移,top:距離body的上偏移}
// 在標準的ie8瀏覽器中,我們使用offsetLeft/offsetTop其實是把父級參照物的邊框已經算在內了,所以我們不需要自己再單獨的加邊框了
function offset(curEle){
var totalLeft = null,
<span style="white-space:pre"> </span>totalTop = null,
par = curEle.offsetParent;
// 首先把自己本身的進行累加:
totalLeft += curEle.offsetLeft;
totalTop += curEle.offsetTop;
// 只要沒有找到body,我們就把父級參照物的邊框和偏移進行累加
while (par){
if(navigator.userAgent.indexOf("MSIE 8.0") === -1){ //不是標準ie8瀏覽器才累加邊框
// 累加父級參照物的邊框
totalLeft += par.clientLeft;
totalTop += par.clientTop;
}
// 累加父級參照物的偏移
totalLeft += par.offsetLeft;
totalTop += par.offsetTop;
par = par.offsetParent;
}
return {left:totalLeft,top:totalTop};
}
console.log(offset(center));
console.log(offset(center).left);
3.3 scroll系列
3.3.1 scrollWidth/scrollHeight (只讀屬性)
● 容器中內容沒有溢位的情況下:和我們的clientWidth/clientHeight一模一樣
● 如果容器中內容有溢位,獲取的結果如下規則:
scrollWidth:真實內容的寬度(包含溢位)+左填充
scrollHeight:真實內容的高度(包含溢位)+上填充
獲取到的結果都是“約等於”的值,因為:
● 同一個瀏覽器,我們是否設定overflow="hidden",對於最終的結果是有影響的(滾動條也佔據寬度會影響);
● 在不同的瀏覽器中我們獲取到的結果也是不相同的
3.3.2 scrollLeft/scrollTop(可讀寫屬性)
滾動條捲去的寬度/高度
注意:
1.之前我們學習的js盒子模型中:client系列/offset系列/scrollWidth/scrollHeight都是“只讀”屬性->只能通過屬性獲取值,不能通過屬性修改元素的樣式
2.scrollTop/scrollLeft:滾動條捲曲的高度/寬度(這兩個屬性是唯一“可讀寫”屬性)
scrollTop的值是存在邊界值(最大和最小值的),我們設定的值比最小值小或者比最大值大時都沒用,起到效果的依然是邊界的值。
[最小值是零]
box.scrollTop = -1000; //直接回到容器頂部,沒有超出
console.log(box.scrollTop);
[最大值=真實的高度-當前容器一螢幕的高度]
var maxTop = box.scrollHeight - box.clientHeight;
console.log(maxTop);
4. 關於js盒子模型屬性取值的問題
我們通過以上這些屬性值獲取的結果永遠不可能出現小數,都是整數;
瀏覽器獲取結果的時候,會在原來真實結果的基礎上進行四捨五入。
5. 關於操作瀏覽器本身的盒子模型資訊
5.1 clientWidth/clientHeight
是當前瀏覽器可視視窗的寬/高(一螢幕的寬/高)
5.2 scrollWidth/scrollHeight
是當前頁面的真實寬/高(所有屏加起來的寬/高),但是是一個約等於的值
5.3 注意
● 不管哪些屬性,也不管是什麼瀏覽器,也不管是獲取還是設定,想要都相容的話,需要寫兩套;
● 且必須document.documentElement在前
document.documentElement[attr] || document.body[attr];
如:
[獲取]
document.documentElement.clientHeight || document.body.clientHeight
[設定]
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
win:編寫一個有關於操作瀏覽器盒子模型的方法
如果只傳遞了attr沒有傳遞value,預設的意思的“獲取”
如果兩個引數都傳遞了,意思是“設定”
不嚴謹的來說這就是有關於“類的過載”:同一個方法,通過傳遞引數的不同實現了不同的功能
function win(attr,value){
if(typeof value === "undefined"){
return document.documentElement[attr] || document.body[attr];
}
document.documentElement[attr] = value;
document.body[attr] = value;
}
win("clientHeight");
補充
parentNode:父親節點,html結構層級關係中的上一級元素
<div id="outer">
<div id="inner">
<div id="center"></div>
</div>
</div>
var outer = document.getElementById("outer"),
inner = document.getElementById("inner"),
center = document.getElementById("center");
●center.parentNode ->inner●inner.parentNode ->outer
●outer.parentNode ->body
●document.body.parentNode ->
<html>
<head></head>
<body>..</body>
</html>
●document.documentElement.parentNode ->#document:
<!DOCTYPE html>
<html>
<head></head>
<body>..</body>
</html>
●document.parentNode->null