手寫的一個(gè)兼容各種瀏覽器的javascript getStyle函數(shù)(獲取元素的樣式)
要想獲取HTML元素的計(jì)算樣式一直都存在很多的兼容問題,各瀏覽器都會(huì)存在一些差異,F(xiàn)irefox、webkit(Chrome,Safari)支持W3C標(biāo)準(zhǔn)的方法:getComputedStyle(),而IE6/7/8不支持標(biāo)準(zhǔn)的方法但是有私有的屬性來實(shí)現(xiàn):currentStyle,IE9和Opera兩個(gè)都支持。有了這2個(gè)方法和屬性基本上可以滿足大多數(shù)要求了。
var getStyle = function( elem, type ){
return 'getComputedStyle' in window ? getComputedStyle(elem, null)[type] : elem.currentStyle[type];
};
但是對(duì)于自適應(yīng)的寬度和高度使用currentStyle就沒法獲取到計(jì)算的值,只能返回auto,而getComputedStyle()就可以返回計(jì)算的值,解決這個(gè)問題有好幾種辦法。我之前想到的是用clientWidth/clientHeight減去padding的值,這樣就可以在不支持標(biāo)準(zhǔn)方法的瀏覽器中獲取到計(jì)算的寬度和高度。前幾天看到司徒正美采用了另一種辦法,使用getBoundingClientRect()方法獲取到元素在頁面中的位置,然后right減去left就是寬度,bottom減去top就是高度。我對(duì)他的代碼做了一些小小的修改,最終代碼如下:
var getStyle = function( elem, style ){
return 'getComputedStyle' in window ?
getComputedStyle( elem, null )[style] :
function(){
style = style.replace( /\-(\w)/g, function( $, $1 ){
return $1.toUpperCase();
});
var val = elem.currentStyle[style];
if( val === 'auto' && (style === "width" || style === "height") ){
var rect = elem.getBoundingClientRect();
if( style === "width" ){
return rect.right - rect.left + 'px';
}else{
return rect.bottom - rect.top + 'px';
}
}
return val;
}();
};
// 調(diào)用該方法
var test = document.getElementById( 'test' ),
// 獲取計(jì)算的寬度
tWidth = getStyle( test, 'width' );
新的問題,如果元素的寬度或高度使用了em或%的單位,getComputedStyle()返回的值就會(huì)自動(dòng)將em或%換成px的單位,currentStyle就不會(huì),而如果是font-size使用em為單位,在Opera下返回的是0em,Opera真的很恐怖!
后來在使用發(fā)現(xiàn)中還有一些沒想到的兼容問題,今天我對(duì)原來的代碼進(jìn)行了優(yōu)化,并對(duì)一些常見的兼容問題進(jìn)行了處理。
在javascript中“-”(中劃線或連字符)代表的是減號(hào),而在CSS中,許多樣式屬性都有這個(gè)符號(hào),如padding-left、font-size等,所以在javascript中如果出現(xiàn)如下的代碼就一個(gè)錯(cuò)誤:
正確的寫法應(yīng)該是:
這里需要把CSS的中劃線去掉并把原來緊跟在中劃線后的字母大寫,俗稱“駝峰式”寫法,不管是使用javascript設(shè)置或是獲取元素的CSS樣式都應(yīng)該是駝峰式的寫法。但是不少對(duì)CSS熟悉而又對(duì)javascript不太熟悉的新手朋友總是會(huì)犯這種低級(jí)錯(cuò)誤,使用replace的高級(jí)用法可以很簡單的將CSS屬性中的中劃線替換成駝峰式的寫法。
return $1.toUpperCase();
});
對(duì)于float,在javascript中屬于保留字,在javascript中設(shè)置或獲取元素的float的值,都有其他的代替寫法,在標(biāo)準(zhǔn)瀏覽器中為cssFloat,而在IE6/7/8中為styleFloat。
如果top、right、bottom、left沒有一個(gè)顯式的值,在獲取這些值的時(shí)候部分瀏覽器會(huì)返回一個(gè)auto,雖然auto這個(gè)值是一個(gè)合法的CSS屬性值,但絕不是我們想要的結(jié)果,而應(yīng)該是0px。
在IE6/7/8中要設(shè)置元素的透明度需要用到濾鏡、如:filter:alpha(opacity=60),對(duì)于標(biāo)準(zhǔn)瀏覽器直接設(shè)置opacity即可,IE9兩種寫法都支持,我對(duì)獲取元素的透明度也做了兼容處理,只要使用opacity就可以獲取到所有瀏覽器元素的透明度的值。
在IE6/7/8中獲取元素的寬度和高度已經(jīng)在上篇文中介紹過了,這里就不再復(fù)述了。還有一個(gè)需要注意的地方就是,如果元素的樣式是使用style內(nèi)聯(lián)的寫法,或者是已經(jīng)使用javascript設(shè)置過樣式的屬性,可以使用下面的方法獲取到元素的計(jì)算樣式:
var height = elem.style.height;
這個(gè)方法比讀取getComputedStyle或currentStyle中的屬性值都要快,應(yīng)該優(yōu)先使用,當(dāng)然前提條件就是樣式是通過內(nèi)聯(lián)的寫法設(shè)置的(使用javascript設(shè)置也是設(shè)置內(nèi)聯(lián)樣式)。優(yōu)化過的最終代碼如下:
var getStyle = function( elem, p ){
var rPos = /^(left|right|top|bottom)$/,
ecma = "getComputedStyle" in window,
// 將中劃線轉(zhuǎn)換成駝峰式 如:padding-left => paddingLeft
p = p.replace( /\-(\w)/g, function( $, $1 ){
return $1.toUpperCase();
});
// 對(duì)float進(jìn)行處理
p = p === "float" ? ( ecma ? "cssFloat" : "styleFloat" ) : p;
return !!elem.style[p] ?
elem.style[p] :
ecma ?
function(){
var val = getComputedStyle( elem, null )[p];
// 處理top、right、bottom、left為auto的情況
if( rPos.test(p) && val === "auto" ){
return "0px";
}
return val;
}() :
function(){
var <a >wirelesscasinogames.com</a> val = elem.currentStyle[p];
// 獲取元素在IE6/7/8中的寬度和高度
if( (p === "width" || p === "height") && val === "auto" ){
var rect = elem.getBoundingClientRect();
return ( p === "width" ? rect.right - rect.left : rect.bottom - rect.top ) "px";
}
// 獲取元素在IE6/7/8中的透明度
if( p === "opacity" ){
var filter = elem.currentStyle.filter;
if( /opacity/.test(filter) ){
val = filter.match( /\d / )[0] / 100;
return (val === 1 || val === 0) ? val.toFixed(0) : val.toFixed(1);
}
else if( val === undefined ){
return "1";
}
}
// 處理top、right、bottom、left為auto的情況
if( rPos.test(p) && val === "auto" ){
return "0px";
}
return val;
}();
};
下面是調(diào)用示例:
<style>
.box{
width:500px;
height:200px;
background:#000;
filter:alpha(opacity=60);
opacity:0.6;
}
</style>
<div id="box"></div>
<script>
var box = document.getElementById( "box" );
alert( getStyle(box, "width") ); // "500px"
alert( getStyle(box, "background-color") ); // "rgb(0, 0, 0)" / "#000"
alert( getStyle(box, "opacity") ); // "0.6"
alert( getStyle(box, "float") ); // "none"
</script>
- javascript獲取設(shè)置div的高度和寬度兼容任何瀏覽器
- javascript使用百度地圖api和html5特性獲取瀏覽器位置
- javascript獲取瀏覽器類型和版本的方法(js獲取瀏覽器版本)
- javascript獲取和判斷瀏覽器窗口、屏幕、網(wǎng)頁的高度、寬度等
- JavaScript獲取網(wǎng)頁、瀏覽器、屏幕高度和寬度匯總
- javascript 獲取瀏覽器版本
- javascript實(shí)現(xiàn)獲取瀏覽器版本、操作系統(tǒng)類型
- JavaScript跨瀏覽器獲取頁面中相同class節(jié)點(diǎn)的方法
- JavaScript獲取各大瀏覽器信息圖示
相關(guān)文章
JavaScript高級(jí)程序設(shè)計(jì)閱讀筆記(十六) javascript檢測(cè)瀏覽器和操作系統(tǒng)-detect.js
javascript檢測(cè)瀏覽器和操作系統(tǒng) detect.js使用介紹,需要的朋友可以參考下2012-08-08詳細(xì)分析jsonp的原理和實(shí)現(xiàn)方式
給大家圖文詳細(xì)分析一下jsonp的原理以及跨域問題的匯總。2017-11-11js中將URL中的參數(shù)提取出來作為對(duì)象的實(shí)現(xiàn)代碼
將URL中的參數(shù)提取出來作為對(duì)象的實(shí)現(xiàn)代碼,適合希望獲取url參數(shù)的朋友。2011-08-08使用BootStrap實(shí)現(xiàn)用戶登錄界面UI
本文給大家介紹使用BootStrap實(shí)現(xiàn)用戶登錄界面UI,布局風(fēng)格采用左右各一半的風(fēng)格設(shè)計(jì),非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-08-08用Javascript數(shù)組處理多個(gè)字符串的連接問題
小技巧 用Javascript數(shù)組處理多個(gè)字符串的連接問題,大家可以參考下。2009-08-08HTML+JavaScript實(shí)現(xiàn)掃雷小游戲
這篇文章主要為大家詳細(xì)介紹了HTML+JavaScript實(shí)現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09