目錄
- getComputedStyle 與getPropertyValue
- IE 下的 currentStyle與getAttribute
- style 與getComputedStyle
- getComputedStyle 與defaultView
- 原生JS實現(xiàn)CSS樣式的get與set
- getStyle(elem, style)
- opacity 透明度的設(shè)定
- float 樣式的獲取
- width | height 樣式的獲取
- 獲取樣式的駝峰表示法
- setStyle(elem, style, value)
getComputedStyle 與getPropertyValue
getComputedStyle 為何物呢,DOM 中 getComputedStyle 方法可用來獲取元素中所有可用的css屬性列表,以數(shù)組形式返回,并且是只讀的。IE678 中則用 currentStyle 代替 。
假設(shè)我們頁面上存在一個 id 為 id 的元素,那么使用getComputedStyle 獲取元素樣式就如下圖所示:
嘗試一下之后可以看到,window.getComputedStyle 獲取的是所有的樣式,如果我們只是要獲取單一樣式,該怎么做呢。這個時候就要介紹另一個方法 --getPropertyValue。
用法也很簡單:
// 語法:
// 使用 getPropertyValue 來指定獲取的屬性
window.getComputedStyle("元素", "偽類").getPropertyValue(style);
IE 下的 currentStyle與getAttribute
說完常規(guī)瀏覽器,再來談?wù)劺吓笥?IE ,與getComputedStyle 對應(yīng),在 IE 中有自己特有的 currentStyle屬性,與 getPropertyValue 對應(yīng),IE 中使用getAttribute 。
和 getComputedStyle 方法不同的是,currentStyle 要獲得屬性名的話必須采用駝峰式的寫法。也就是如果我需要獲取 font-size 屬性,那么傳入的參數(shù)應(yīng)該是 fontSize。因此在IE 中要獲得單個屬性的值,就必須將屬性名轉(zhuǎn)為駝峰形式。
// IE 下語法:
// IE 下將 CSS 命名轉(zhuǎn)換為駝峰表示法
// font-size --> fontSize
// 利用正則處理一下就可以了
function camelize(attr) {
// /\-(\w)/g 正則內(nèi)的 (\w) 是一個捕獲,捕獲的內(nèi)容對應(yīng)后面 function 的 letter
// 意思是將 匹配到的 -x 結(jié)構(gòu)的 x 轉(zhuǎn)換為大寫的 X (x 這里代表任意字母)
return attr.replace(/\-(\w)/g, function(all, letter) {
return letter.toUpperCase();
});
}
// 使用 currentStyle.getAttribute 獲取元素 element 的 style 屬性樣式
element.currentStyle.getAttribute(camelize(style));
style 與getComputedStyle
必須要提出的是,我們使用element.style 也可以獲取元素的CSS樣式聲明對象,但是其與getComputedStyle方法還是有一些差異的。
首先,element.style 是可讀可寫的,而getComputedStyle 為只讀。
其次,element.style 只可以獲取 style 樣式上的屬性值,而無法得到所有的 CSS 樣式值,什么意思呢?回顧一下 CSS 基礎(chǔ),CSS 樣式表的表現(xiàn)有三種方式,
1.內(nèi)嵌樣式(inline Style) :是寫在 HTML 標(biāo)簽里面的,內(nèi)嵌樣式只對該標(biāo)簽有效。
2.內(nèi)部樣式(internal Style Sheet):是寫在 HTML 的 style> 標(biāo)簽里面的,內(nèi)部樣式只對所在的網(wǎng)頁有效。
3.外部樣式表(External Style Sheet):如果很多網(wǎng)頁需要用到同樣的樣式(Styles),將樣式(Styles)寫在一個以 .CSS為后綴的 CSS 文件里,然后在每個需要用到這些樣式(Styles)的網(wǎng)頁里引用這個 CSS 文件。
而element.style 只能獲取被這些樣式表定義了的樣式,而 getComputedStyle 能獲取到所有樣式的值(在不同瀏覽器結(jié)果不一樣,chrome 中是 264,在 Firefox 中是238),不管是否定義在樣式表中,譬如:
style>
#id{
width : 100px;
float:left;
}
/style>
var elem = document.getElementById('id');
elem.style.length // 2
window.getComputedStyle(elem, null).length // 264
getComputedStyle 與defaultView
window.getComputedStyle 還有另一種寫法,就是 document.defaultView.getComputedStyle 。
兩者的用法完全一樣,在 jQuery v1.10.2 中,使用的就是window.getComputedStyle 。如下
也有特例,查看stackoverflow,上面提及到在Firefox 3.6 ,不使用document.defaultView.getComputedStyle 會出錯。不過畢竟 FF3.6 已經(jīng)隨歷史遠(yuǎn)去,現(xiàn)在可以放心的使用window.getComputedStyle。
用一張圖總結(jié)一下:
原生JS實現(xiàn)CSS樣式的get與set
說了這么多,接下來將用原生 JS 實現(xiàn)一個小組件,實現(xiàn) CSS 的 get 與 set,兼容所有瀏覽器。
getStyle(elem, style)
對于 CSS 的 set ,對于支持window.getComputedStyle 的瀏覽器而言十分簡單,只需要直接調(diào)用。
getStyle: function(elem, style) {
// 主流瀏覽器
if (win.getComputedStyle) {
return win.getComputedStyle(elem, null).getPropertyValue(style);
}
}
反之,如果是 IE 瀏覽器,則有一些坑。
opacity 透明度的設(shè)定
在早期的 IE 中要設(shè)置透明度的話,有兩個方法:
1.alpha(opacity=0.5)
2.filter:progid:DXImageTransform.Microsoft.gradient( GradientType= 0 , startColorstr = ‘#ccccc',endColorstr = ‘#ddddd' );
因此在 IE 環(huán)境下,我們需要針對透明度做一些處理。先寫一個 IE 下獲取透明度的方法:
// IE 下獲取透明度
function getIEOpacity(elem) {
var filter = null;
// 早期的 IE 中要設(shè)置透明度有兩個方法:
// 1、alpha(opacity=0)
// 2、filter:progid:DXImageTransform.Microsoft.gradient( GradientType= 0 , startColorstr = ‘#ccccc', endColorstr = ‘#ddddd' );
// 利用正則匹配
filter = elem.style.filter.match(/progid:DXImageTransform.Microsoft.Alpha\(.?opacity=(.*).?\)/i) || elem.style.filter.match(/alpha\(opacity=(.*)\)/i);
if (filter) {
var value = parseFloat(filter);
if (!isNaN(value)) {
// 轉(zhuǎn)化為標(biāo)準(zhǔn)結(jié)果
return value ? value / 100 : 0;
}
}
// 透明度的值默認(rèn)返回 1
return 1;
float 樣式的獲取
float 屬性是比較重要的一個屬性,但是由于 float 是ECMAScript的一個保留字。
所以在各瀏覽器中都會有代替的寫法,比如說在標(biāo)準(zhǔn)瀏覽器中為 cssFloat,而在 IE678 中為 styleFloat 。經(jīng)測試,在標(biāo)準(zhǔn)瀏覽器中直接使用getPropertyValue("float") 也可以獲取到 float 的值。而 IE678 則不行,所以針對 float ,也需要一個 HACK。
width | height 樣式的獲取
然后是元素的高寬,對于一個沒有設(shè)定高寬的元素而言,在 IE678 下使用getPropertyValue("width|height") 得到的是 auto 。而標(biāo)準(zhǔn)瀏覽器會直接返回它的 px 值,當(dāng)然我們希望在 IE 下也返回 px 值。
這里的 HACK 方法是使用 element.getBoundingClientRect() 方法。
element.getBoundingClientRect() --可以獲得元素四個點相對于文檔視圖左上角的值 top、left、bottom、right ,通過計算就可以容易地獲得準(zhǔn)確的元素大小。
獲取樣式的駝峰表示法
上文已經(jīng)提及了,在IE下使用currentStyle 要獲得屬性名的話必須采用駝峰式的寫法。
OK,需要 HACK 的點已經(jīng)提完了。那么在 IE 下,獲取樣式的寫法:
getStyle: function(elem, style) {
// 主流瀏覽器
if (win.getComputedStyle) {
...
// 不支持 getComputedStyle
} else {
// IE 下獲取透明度
if (style == "opacity") {
getIEOpacity(elem);
// IE687 下獲取浮動使用 styleFloat
} else if (style == "float") {
return elem.currentStyle.getAttribute("styleFloat");
// 取高寬使用 getBoundingClientRect
} else if ((style == "width" || style == "height") (elem.currentStyle[style] == "auto")) {
var clientRect = elem.getBoundingClientRect();
return (style == "width" ? clientRect.right - clientRect.left : clientRect.bottom - clientRect.top) + "px";
}
// 其他樣式,無需特殊處理
return elem.currentStyle.getAttribute(camelize(style));
}
}
setStyle(elem, style, value)
說完 get ,再說說 setStyle ,相較于getStyle ,setStyle 則便捷很多,因為不管是標(biāo)準(zhǔn)瀏覽器還是 IE ,都可以使用element.style.cssText 對元素進行樣式的設(shè)置。
cssText -- 一種設(shè)置 CSS 樣式的方法,但是它是一個銷毀原樣式并重建的過程,這種銷毀和重建,會增加瀏覽器的開銷。而且在 IE 中,如果cssText(假如不為空),最后一個分號會被刪掉,所以我們需要在其中添加的屬性前加上一個 ”;” 。
只是在 IE 下的 opacity 需要額外的進行處理。明了易懂,直接貼代碼:
// 設(shè)置樣式
setStyle: function(elem, style, value) {
// 如果是設(shè)置 opacity ,需要特殊處理
if (style == "opacity") {
//IE7 bug:filter 濾鏡要求 hasLayout=true 方可執(zhí)行(否則沒有效果)
if (!elem.currentStyle || !elem.currentStyle.hasLayout) {
// 設(shè)置 hasLayout=true 的一種方法
elem.style.zoom = 1;
}
// IE678 設(shè)置透明度叫 filter ,不是 opacity
style = "filter";
// !!轉(zhuǎn)換為 boolean 類型進行判斷
if (!!window.XDomainRequest) {
value = "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=" + value * 100 + ")";
} else {
value = "alpha(opacity=" + value * 100 + ")"
}
}
// 通用方法
elem.style.cssText += ';' + (style + ":" + value);
}
到這里,原生 JS 實現(xiàn)的 getStyle 與setStyle 就實現(xiàn)了。可以看到,一個簡單接口的背后,都是有涉及了很多方面東西。雖然瀏覽器兼容性是一個坑,但是爬坑的過程卻是我們沉淀自己的最好時機。
jQuery 這樣的框架可以幫助我們走的更快,但是毫無疑問,去弄清底層實現(xiàn),掌握原生 JS 的寫法,可以讓我們走得更遠(yuǎn)。
以上就是解析原生JS getComputedStyle的詳細(xì)內(nèi)容,更多關(guān)于原生JS getComputedStyle的資料請關(guān)注腳本之家其它相關(guān)文章!
您可能感興趣的文章:- 前端學(xué)習(xí)筆記style,currentStyle,getComputedStyle的用法與區(qū)別
- JS獲取CSS樣式(style/getComputedStyle/currentStyle)
- JS使用getComputedStyle()方法獲取CSS屬性值
- getComputedStyle與currentStyle獲取樣式(style/class)
- javascript 讀取內(nèi)聯(lián)之外的樣式(style、currentStyle、getComputedStyle區(qū)別介紹)
- 用javascript getComputedStyle獲取和設(shè)置style的原理