getComputedStyle與currentStyle

孫群發表於2013-12-15

本文參考https://developer.mozilla.org/en-US/docs/Web/API/Window.getComputedStyle


1.簡介

   getComputedStyle是window下的一個全域性函式,可以獲取元素真正使用的樣式。


2.語法   

var style = window.getComputedStyle(element[, pseudoElt]);
element是用於計算樣式的dom節點,pseudoElt是一個用於匹配偽類的字串,對於一般的dom元素來說,該引數應該被忽略或設定為null。需要注意的是在Gecko核心2.0(即Firefox4)之前該引數是必須的,對於其他主流瀏覽器來說該引數非必須,現在Firefox已經與其他瀏覽器一樣將該引數設為optional,所以為了相容性考慮,在沒有匹配偽類的情況下,第二個引數最好傳null。

還有一點需要說明的是,在Firefox3.6下,如果要獲取框架樣式(framed styles),必須要使用document.defaultView.getComputedStyle()而不能使用window.getComputedStyle()。那defaultView又是何物?其實defaultView返回的是document 物件所關聯的 window 物件,如果沒有,會返回 null。該屬性為只讀,IE 9 以下版本不支援 defaultView。

示例

<style>
 #elem-container{
   position: absolute;
   left:     100px;
   top:      200px;
   height:   100px;
 }
</style>

<div id="elem-container">dummy</div>
<div id="output"></div>  

<script>
  function getTheStyle(){
    var elem = document.getElementById("elem-container");
    var theCSSprop = window.getComputedStyle(elem,null).getPropertyValue("height");
    document.getElementById("output").innerHTML = theCSSprop;
   }
  getTheStyle();
</script>

3.與element.style的區別

首先,element.style屬性不僅可讀,而且可寫,而getComputedStyle獲取的樣式是隻讀的;其次,element.style獲取的樣式是很有限定的,只能獲取那些我們顯式的設定的內聯css樣式,對於瀏覽器預設設定、外部樣式表以及內部樣式表(位於 <head> 標籤內部)都輸出空字串,而getComputedStyle會輸出最終應用於該element上的最終樣式,而不管該樣式是內聯的還是外聯的還是瀏覽器預設的,總之不會輸出空字串。就拿csdn部落格這個頁面舉例來說,我們注意一下document.body的background樣式,如下圖


body的內聯樣式為空,但在內部樣式表中設定了background樣式,在控制檯下用分別用style和getComputedStyle檢測結果,如下圖所示



4.瀏覽器相容性

桌面瀏覽器

 

IE9以下版本不支援getComputedStyle方法,恰如上文所說,IE9以下的document沒有defaultView屬性,所以只要是支援getComputedStyle的瀏覽器都可以呼叫document.defaultView.getComputedStyle()。所有版本的IE以及Opera的getComputedStyle方法都不支援偽類。

手機瀏覽器


手機瀏覽器對getComputedStyle方法基本都支援。


5.IE的currentStyle

如上文所說,IE8以及IE8以下的IE都不支援getComputedStyle方法,不過IE這坨奇葩提供了另一個屬性element.currentStyle。到目前本文撰寫為止,IE最新的瀏覽器IE11也保留該屬性,也就是說IE9+的瀏覽器既可以使用getComputedStyle也可以使用element.currentStyle屬性。element.currentStyle的示例如下:

document.body.currentStyle.getAttribute('backgroundColor')

getComputedStyle和element.currentStyle主要存在以下區別:

a.前者在很多瀏覽器上(except IE)都支援偽類,currentStyle完全不支援偽類;

b.前者使用getPropertyValue獲取樣式,後者使用getAttribute獲取樣式;

c.getPropertyValue中傳入的變數不支援駝峰標示,多單詞的css屬性名只能以“-”連線,比如getPropertyValue("background-color")合法,而getPropertyValue("backgroundColor")非法;IE有時候傳入“-”連線符變數可以獲取正確結果,有時候傳入駝峰標識變數能獲取正確結果,IE11下測試如下圖

 

d.在獲取width、height等表示空間大小的樣式時,getComputedStyle一般都返回具體的畫素大小,比如“200px”,是一個絕對的大小;而currentStyle返回的有可能不是絕對值而是之前設定的相對值,比如“50%”等,以下為在IE11下對百度首頁的測試結果


其實在大部分情況下,width、height等的絕對值對我們的用處更大,而且currentStyle也只是微軟自家的屬性,不是標準,所以在IE9+的瀏覽器下推薦使用getComputedStyle


6.相容所有瀏覽器計算樣式的程式碼

//將名稱轉換成駝峰標誌的形式
	function toCamelCase(name){
		var result = "";
		var words = name.split("-");
		for(var i=0;i<words.length;i++){
			var word = words[i].toLowerCase();
			if(i !== 0){
				word = word[0].toUpperCase() + word.slice(1,word.length);
			}
			result += word;
		}
		return result;
	}

	//將變數名稱轉換成"-"連線符形式
	function toHyphen(name){
		var result = "";
		for(var i=0;i<name.length;i++){
			var c = name[i];
			if(i !== 0){
				if(c.match(/[A-Z]/g)){
					c = "-"+c.toLowerCase();
				}
			}
			result += c;
		}
		return result;
	}

	//通過currentStyle得到樣式
	function _getStyleforIE(dom,styleName){
		var result = null;
		if(dom.currentStyle){
			styleName = toHyphen(styleName);
			result = dom.currentStyle.getAttribute(styleName);
			if(!result){
				styleName = toCamelCase(styleName);
				result = dom.currentStyle.getAttribute(styleName);
			}
		}
		return result;
	}

	//相容所有瀏覽器的計算樣式的方法
	function getElementComputedStyle(dom,styleName){
		if(!(dom instanceof HTMLElement)){
			return null;
		}
		if(typeof styleName !== "string"){
			return null;
		}
		else{
			styleName = styleName.replace(/\s/,"");
			if(styleName === ""){
				return null;
			}
		}

		var style = null;

		if(document.defaultView){					
			var domStyles = document.defaultView.getComputedStyle(dom,null);
			styleName = toHyphen(styleName);
			style = domStyles.getPropertyValue(styleName);
			if(!style){
				if(dom.currentStyle){
					style = _getStyleforIE(dom,styleName);
				}
			}
		}
		else if(dom.currentStyle){
			style = _getStyleforIE(dom,styleName);
		}

		return style;
	}


在使用時呼叫getElementComputedStyle方法即可。

相關文章