標籤:javascript
頁面往往是動態變化的,我們經常需要在指令碼裡對元素的樣式進行操作,剛學習js的時候大家都知道通過style屬性設定css樣式相關的屬性,但有時候也想先擷取樣式,結果發現通過style取到的值是空,這就需要我們對這些概念足夠熟練。
一、設定樣式
每個dom元素都具有一個style屬性,與平常的屬性不一樣,style的值是一個CSSStyleDeclaration對象,這個對象的屬性代表了該對應元素的內聯樣式。
注意上面說的是內聯樣式,我們知道,在<link>
內引用的樣式稱為外部樣式,在<style>
標籤內書寫的樣式稱為外聯樣式,而在元素標籤內通過style屬性直接賦值的就叫內聯樣式。
雖然大多數情況下我們都使用的是外部樣式,但同等條件下,內聯樣式的優先順序是高於外部樣式的,我們給元素的style屬性賦值,就相當與給其指定了內聯樣式,所以覆蓋了原先相同屬性的樣式。這也是為什麼有時候通過style屬性拿不到值的原因:因為你並沒有給元素指定內聯樣式。
<style> #box{ width: 100px; height: 100px; /* 在外聯樣式內設定color值 */ color: #fff; background-color: #ff9000; }</style>
<!--在內聯樣式中設定position--><div id="box" style="position: relative">盒子</div>
var box = document.getElementById("box");console.log(box.style.color); //空,因為沒有在內聯樣式內設定color屬性console.log(box.style.position); //輸出"relative", 因為在內聯樣式中設定了positionbox.style.color = "#000"; //成功設定color值console.log(box.style.color); //輸出"rgb(0, 0, 0)",因為剛才已經設定
命名規範
因為在js中連字號就是減號,所以在css裡類似與font-size: 20px
這種帶有連字號的屬性是不能直接通過style.font-size訪問的,應該將連字號去掉,並將連字號後面第一個字母大寫,或者通過數組訪問形式賦值,如:
box.style.fontSize = "20px";//或 box.style["font-size"] = "20px"
另外對於在js中是保留字元的屬性如float,最好給其加入css首碼使其成為一個合法的屬性,如
box.style.cssFloat = "left";
注意
style的所有屬性的值都應該是字串,在使用style設定定位屬性時,所有定位屬性都需要包含單位。
box.style.left = 300; //無效,300不是字串box.style.left = "300"; //無效,沒有帶單位box.style.left = "300px"; //這就對了
綜上,使用style對於設定樣式還是比較方便的,但對於讀取樣式就非常困難了,首先返回的值都帶有單位,其次對於像margin這種複合屬性因為擷取的是字串,所以還需要對其進行拆分出四個方向的值。
最後,通過setAttribute和設定style的cssText值,也可以一次性寫好所有樣式,一次性賦值給元素:
var s = "float: left; margin: 0 10px;"box.setAttribute("style", s);//或者box.style.cssText = s;//讀取也是一樣的s = box.getAttribute("style");//或者s = box.style.cssText;
擷取計算樣式
我們一般情況下其實並不關心到底是內聯樣式還是外聯樣式,只是想擷取元素的樣式值,元素最終顯示時實際使用的屬性值就成為計算樣式。
計算樣式也是一個CSSStyleDeclaration對象,通過window對象調用。(IE8以下不支援)
var styles = window.getComputedStyle(element, ":before");
可以看到,第一個參數代表需要擷取樣式的元素,第二個參數代表偽對象的字串,如果不需要可以設定成null或Null 字元串。
同樣使用屬性進行訪問:
var styles = window.getComputedStyle(box, "");console.log(styles.marginLeft); //輸出"0px",雖然並沒有顯示指定過marginLeft
區別
雖然通過style和getComputedStyle擷取到的都是CSSStyleDeclaration對象,但它們還是有些區別的。
- 後者(通過getComputedStyle擷取到的CSSStyleDeclaration對象)的屬性都是唯讀。
- 後者的值都是絕對值,也就是說你設定的可能是”50%”這種百分比,到最後擷取到的都是具體的數值,尺寸大小表示為px為尾碼的字串,顏色表示為“rgb(#, #, #)”或 “rgba(#, #, # ,#)”。
- 不計算複合屬性如margin,將返回Null 字元串(根據瀏覽器而不同,chrome支援返回)。最好使用具體的屬性如marginLeft等。
- 沒有cssText屬性,將返回Null 字元串(根據瀏覽器而不同,chrome支援返回)。
- 對於定位屬性,如果不是絕對位置,訪問left、top等定位屬性都返回”auto”
所以我們既要讀取樣式又要設定樣式的時候可以結合二者進行使用。如
var box = document.getElementById("box");var styles = window.getComputedStyle(box, "");//將文本尺寸放大兩倍var size = parseInt(styles.fontSize);box.style.fontSize = size * 2 + "px";
對於IE,有其自身的CSSStyleDeclaration對象,通過currentStyle擷取。
三、設定類名
很早以前,擷取一個元素的類名都是通過className屬性擷取的,對於只有單個類名的元素好說,一旦元素具有多個類名,得到的將是多個類名通過空格符隔開的字串,需要自行進行分解。
<div id="box" class="red btn whatever">盒子</div>
var box = document.getElementById("box");console.log(box.className); //"red btn whatever"
在HTML5裡面,元素新增了一個classList屬性,它是一個唯讀對象,但提供了操作類名非常方便的方法:
- add(className) 添加類名
- remove(className) 移除類名
- toggle(className) 如果不存在此類名則添加,存在則刪除這個類名
- contains(className) 檢測是否包含指定的類名
有了這些方法就方便多了(對於不支援的瀏覽器,當然其實你也可以自己去實現這些方法)
var classList = box.classList;classList.add("aaa");console.log(box.className); //"red btn whatever aaa"classList.remove("red");console.log(box.className); //"btn whatever aaa"classList.toggle("bbb");console.log(box.className); //"btn whatever aaa bbb"classList.contains("aaa"); //true
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Javascript 操作CSS 學習筆記