腳本化CSS 我們剛講過如何獲取和設置行內樣式的值,但是我們開發不會所有樣式都寫在行內,同時js沒法獲取內嵌樣式表和外部樣式表中的值. 事實上DOM提供了可靠的API,得到計算後的樣式。 1. 獲取計算樣式表 只讀,不可寫 獲取的值是計算後的絕對值,不是相對值 window.getComputedS ...
腳本化CSS
我們剛講過如何獲取和設置行內樣式的值,但是我們開發不會所有樣式都寫在行內,同時js沒法獲取內嵌樣式表和外部樣式表中的值.
事實上DOM提供了可靠的API,得到計算後的樣式。
1. 獲取計算樣式表
只讀,不可寫
獲取的值是計算後的絕對值,不是相對值
window.getComputedStyle(ele,null).attr IE8以上
ele.currentStyle IE8及其以下
例子:
window.getComputedStyle(ele).attr
// 當然window是可以省略的
getComputedStyle(ele).attr
好用的東西,一定不相容。所以IE6、7、8不相容
附加在元素身上的currentStyle屬性,它表現和style點語法一樣,使用駝峰式訪問
例子
oDiv.currentStyle.width
之前講過,點操作符必須符合標識符的規範,所以使用點操作符獲取有連字元的屬性要寫成駝峰式
getComputedStyle(oDiv).backgroundColor;
oDiv.currentStyle.backgroundColor;
中括弧操作符,因為中括弧內寫字元串,所以不用遵循標識符規範,就可以保留連字元的寫法
getComputedStyle(oDiv)['background-color'];
oDiv.currentStyle['background-color'];
顏色值在高級瀏覽器中是rgb()格式,低級瀏覽器中就是原樣輸出。
示例:
封裝getStyle(dom,attr)相容性
實際上,老司機都不這麼做。我們不關心你的版本是什麼,我只關心你的能力。
function getStyle(ele,attr){
if(window.getComputedStyle){
return getComputedStyle(ele)[attr];
}else{
return ele.currentStyle[attr];
}
}
function getStyle(dom,attr){
if(dom.currentStyle){ // IE8 及其一下
return dom.currentStyle[attr]
}else{
return getComputedStyle(dom,null)[attr]
}
}
現在我們要在一個輪子,就是封裝一個函數,這個函數接收兩個參數,第一個是對象,第二個是屬性名。
getStyle(obj,”padding-left”);
getStyle(obj,”paddingLeft”);
這個函數返回的是這個屬性值的計算後的樣式。更牛逼的是,我們無論用戶輸入的是駝峰還是非駝峰,都讓這個函數魯棒。
2. 操作元素樣式
我們知道前面學過瞭如果設置樣式通過行內style來設置元素樣式,
那麼我們就可以通過獲取計算樣式值,然後修改
var oBox = document.getElementById('box');
var wid = parseInt(getStyle(oBox,'width'));
oBox.onclick = function(){
wid += 20;
console.log(wid);
oBox.style.width = wid + 'px';
}
3. 快捷位置和尺寸
DOM已經提供給我們計算後的樣式,但是還覺得不方便,所以DOM又提供給我們一些API:
獲取元素的顯示尺寸(數字類型的值)
ele.offsetWidth width+左右padding+左右border
ele.offsetHeight height+上下padding+上下border
ele.offsetLeft 水平距離 (常用)
ele.offsetTop 豎直距離 (常用)
ele.clientWidth width+左右padding (常用)
ele.clientHeight height+上下padding (常用)
dom.clientLeft 上邊框的width (可不記)
dom.clientTop 左邊框的width (可不記)
3.1. offsetWidth和offsetHeight
全線相容,是自己的屬性,和別的盒子無關。
一個盒子的offsetWidth值就是自己的 width+左右padding+左右border的寬度(說白就是盒子的大小)
總結一下,全線相容。
3.2. offsetLeft屬性和offsetTop
這兩個屬性的相容性非常差,不要著急,我們慢慢來看。
IE9、IE9+、Chrome等高級瀏覽器:
一個元素的offsetLeft值,就是這個元素左邊框外,到自己的offsetParent對象的左邊框內的距離
每一個元素,天生都有一個屬性,叫做offsetParent
就是自己祖先元素中,離自己最近的已經定位的元素,如果自己的祖先元素中,沒有任何盒子進行了定位,那麼offsetParent對象就是body。
op.offsetParent; // 查找離自己最近的定位父級
無論這個盒子自己是否定位,自己的offsetParent就是按照上述方法尋找。
IE6、IE7:
IE6、7的offsetParent對象是誰,和高級瀏覽器有非常大的不同。
情形1:自己如果沒有定位屬性,那麼自己的offsetParent對象就是自己的祖先元素中離自己最近的有width或者有height的元素:
<div class="box1">
<div class="box2"> → 你好,我有寬度 , offsetParent
<div class="box3"> → 你好,我沒有寬高
<p></p> → 你好,我沒有定位
</div>
</div>
</div>
情形2:自己如果有定位屬性
那麼自己的offsetParent就是自己祖先元素中離自己最近的有定位的元素。
<div class="box1">
<div class="box2">
<div class="box3"> → 你好,我沒有寬高,有定位 , offsetParent
<p></p> → 你好,我沒有定位
</div>
</div>
</div>
數值就是自己的左外邊框到offsetParent對象的左內邊框的值。
IE8:
IE8的offsetParent是誰呢?和高級瀏覽器一致:
無論自己是否定位,自己的offsetParent就是自己祖先元素中,離自己最近的已經定位的元素。
這一點,沒有任何相容問題!
相容性解決辦法,不是能力檢測,也不是版本檢測,而是善用這個屬性,要確保屬性的使用條件:
這樣的話,所有瀏覽器的值都是一樣的,offsetLeft、offsetTop值是number類型的,可以直接參与運算,不需要parseInt()
3.3. clientWidth和clientHeight
clientWidth就是自己的width+padding的值。 也就是說,比offsetWidth少了border。
如果盒子沒有高度,用文字撐的,IE6 clientHeight是0,其他瀏覽器都是數值。
以上6個屬性要銘記於心,就offsetLeft、offsetTop比較鬧騰,但是合理使用,也沒相容問題了
3.4. clientLeft和clientTop
這兩個屬性沒有太大的意義就是上邊框和左邊看的寬度而已
4. 獲取元素的有定位屬性的父級
ele.offsetParent
如果沒有定位父節點,則返回body
封裝getElementPosition函數,獲取元素相對於文檔的坐標
function getElePos(dom){ // 獲取元素相對於文檔的坐標
var x = dom.offsetLeft;
var y = dom.offsetTop;
var parent = dom.offsetParent;
while(parent !== null){
x += parent.offsetLeft;
y += parent.offsetTop;
parent = parent.offsetParent;
}
return {
x: x,
y: y
}
}
5. 獲取元素的滾動值
5.1 獲取滾動元素的寬高
當元素實際內容超過設置的內容時
dom.scrollWidth ==> 元素實際內容的width
dom.scrollHeight ==> 元素實際內容的height
5.2 獲取元素的滾動距離(數字類型的值)
dom.scrollLeft 滾動的水平距離
dom.scrollTop 滾動的豎直距離
5.3 滾動距離的相容寫法
- 獲取滾動條的滾動距離 IE8以上
window.pageXOffset 頁面滾動的水平距離
window.pageYOffset 頁面滾動的豎直距離
- 獲取滾動條的滾動距離 IE8及其以下
document.documentElement.scrollLeft IE7,8
document.documentElement.scrollTop IE7,8
document.body.scrollLeft
document.body.scrollTop
在IE8以上相容性比較混亂,在使用時兩個值相加,因為這兩對值不能同時存在
封裝getScrollOffset相容性函數
function getScrollOffset(){
if(window.pageYOffset){
return {
x: window.pageXOffset,
y: window.pageYOffset
}
}else{
return {
x: document.documentElement.scrollLeft + document.body.scrollLeft,
y: document.documentElement.scrollTop + document.body.scrollTop;
}
}
}
6. 獲取瀏覽器視窗的尺寸
IE8以上
window.innerWidth 視窗的寬度(包含滾動條)
window.innerHeight 視窗的高度(包含滾動條)
IE8及其以下
document.documentElement.clientWidth 標準模式下
document.documentElement.clientHeight
(在Chrome,Firefox,IE7,IE8不包含滾動條,在IE8以上包含滾動條)
document.body.clientWidth 怪異模式下
document.body.clientWidth
檢測瀏覽器是不是在怪異模式下
dowument.compatMode === 'BackCompat'
封裝getViewportOffset相容性函數
function getViewportOffset(){
if(window.innerWidth){
return {
x: window.innerWidth,
y: window.innerHeight
}
}else{
if( document.compatMode === 'BackCompat'){
return {
x: document.body.clientWidth,
y: document.body.clientHeight
}
}else{
return {
x: document.documentElement.clientWidth,
y: document.documentElement.clientHeight
}
}
}
}
7. 設置滾動條的滾動距離
瀏覽器頁面滾動
window.scrollTo(x,y) 讓滾動條滾動到指定位置
window.scrollBy(x,y) 讓滾動條滾動指定距離
頁面元素滾動
ele.scrollTo(x,y)
ele.scrollBy(x,y)