習慣了用jQuery的css()的方法獲取元素的css屬性,突然不用jquery了,當要獲得元素的css時候,我瞬間停頓了一下,咦?咋獲取元素的css值?比如獲取元素的width。是這樣么?document.getElementById("id").style.width?
一、getComputedStyle
getComputedStyle,見名之意,就是獲取元素計算之后的樣式屬性值,也就是獲取當前元素所有最終使用的CSS屬性值。返回的是一個CSS樣式聲明對象([object CSSStyleDeclaration]),注意是只讀。
語法:var style = window.getComputedStyle("元素", "偽類");
說明:第二個參數可以省略
如獲得元素的width:
var ele = document.getElementById("XXX");
var _width = window.getComputedStyle(ele).width;
二、getComputedStyle與style的區別
1、getComputedStyle方法是只讀的,只能獲取樣式,不能設置;
2、element.style能讀取,能設置,但是注意,只能讀取元素中style屬性中的樣式。
3、getComputedStyle能獲取所有的css屬性,包括默認的。
三、getComputedStyle與defaultView
defaultView又是什么東東?jQuery獲取樣式方式就是如下:
var getStyles = function( elem ) { // Support: IE <=11 only, Firefox <=30 (#15098, #14150) // IE throws on elements created in popups // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" var view = elem.ownerDocument.defaultView; if ( !view || !view.opener ) { view = window; } return view.getComputedStyle( elem ); };
雖然window上命名有getComputedStyle屬性了,直接但是使用window.getComputedStyle(ele)不會有啥問題,但是在火狐就會有問題,jQuery也在備注中寫好了。
四、getComputedStyle兼容性
別想了,此處IE不整點名堂怎么證明當初它式瀏覽器中的一霸主呢?
IE給自己提供了一套方法。IE中使用currentStyle代替getComputedStyle
如獲得元素width:
element.currentStyle? element.currentStyle : window.getComputedStyle(element, null)).width;
五、獲取元素樣式的兼容性封裝
function getCss(obj,attribute) { if(obj.currentStyle) { return obj.currentStyle[attribute];} else { return window.getComputedStyle(obj,null)[attribute]; } }
如獲取id為button的背景顏色
var _btn = document.getElementById("button");
console.log(getCss(_btn, 'backgroundColor'));
五、思考
getComputedStyle會引起回流,因為它需要獲取祖先節點的一些信息進行計算(譬如寬高等),所以用的時候慎用,回流會引起性能問題。
回流:
也稱為Reflow,即回流。一般意味着元素的內容、結構、位置或尺寸發生了變化,需要重新計算樣式和渲染樹
什么會引起回流?
1.頁面渲染初始化
2.DOM結構改變,比如刪除了某個節點
3.render樹變化,比如減少了padding
4.窗口resize
5.最復雜的一種:獲取某些屬性,引發回流。
很多瀏覽器會對回流做優化,會等到數量足夠時做一次批處理回流,但是除了render樹的直接變化,當獲取一些屬性時,瀏覽器為了獲得正確的值也會觸發回流,這樣使得瀏覽器優化無效,包括:
-
offset(Top/Left/Width/Height)
-
scroll(Top/Left/Width/Height)
-
cilent(Top/Left/Width/Height)
-
width,height
-
調用了getComputedStyle()或者IE的currentStyle
- 修改字體
回流一定伴隨着重繪,重繪卻可以單獨出現。所以一般會有一些優化方案,如:
-
減少逐項更改樣式,最好一次性更改style,或者將樣式定義為class並一次性更新
-
避免循環操作dom,創建一個documentFragment或div,在它上面應用所有DOM操作,最后再把它添加到window.document
-
避免多次讀取offset等屬性。無法避免則將它們緩存到變量
-
將復雜的元素絕對定位或固定定位,使得它脫離文檔流,否則回流代價會很高
六、另記
怎樣用 JavaScript 准確獲取手機屏幕的寬度和高度?
function getViewportSize () { return { width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight }; }