第一部分:接口介紹
首先說(shuō)在HTML中定義樣式的方式有 3 種:
- 通過(guò)
link元素包含外部樣式表文件 - 使用
style元素定義嵌入式樣式 - 使用
style特性定義針對(duì)特定元素的樣式
DOM2級(jí)模塊圍繞這三種應(yīng)用樣式機(jī)制提供了一套API。理解了這套API就理解了如何用JS操作CSS了。這套接口種類很多。如下圖:
可以參考MDN這篇文章了解。
接口都是有規(guī)律的,死記硬背不好記住,根據(jù)HTML中定義樣式的3種方式來(lái)看接口的定義,自然就更好理解。
1.1 CSSStyleSheet樣式表對(duì)象
名字中帶有StyleSheet的接口就樣式表的意思。CSSStyleSheet接口類型表示的是樣式表。包括通過(guò)link元素包含的外部樣式表和在<style type="text/css"></style>元素中定義的樣式表。CSSStyleSheet接口繼承StyleSheet。StyleSheet可以作為一個(gè)基礎(chǔ)接口來(lái)定義非 CSS 樣式表。
1.2 CSSRule樣式表規(guī)則對(duì)象
名字中帶有Rule的接口就代表規(guī)則的意思。CSSRule對(duì)象表示樣式表中的每一條規(guī)則。CSSRule其實(shí) 是一個(gè)供其他多種類型繼承的基類型。其中最常用的就是 CSSStyleRule 類型,表示樣式信息。
CSSRule的所有子類型如下:
CSSCharsetRuleCSSConditionRuleCSSCounterStyleRuleCSSFontFeatureValuesRuleCSSGroupingRuleCSSImportRuleCSSKeyframeRuleCSSKeyframesRuleCSSMarginRuleCSSMediaRuleCSSNamespaceRuleCSSPageRuleCSSSupportsRuleCSSViewportRuleCSSFontFaceRuleCSSStyleRule
這些規(guī)則很少有必要通過(guò)腳本來(lái)訪問(wèn),而最常用的就是
CSSStyleRule類型。
通過(guò)下圖可以加深對(duì)StyleSheet,CSSRule關(guān)系的理解。
1.3 CSSStyleDeclaration 應(yīng)用在元素style屬性的對(duì)象
任何支持style特性的HTML元素在JavaScript中都有一個(gè)對(duì)應(yīng)的style屬性。這個(gè)style對(duì)象是 CSSStyleDeclaration的實(shí)例。包含著通過(guò)HTML的style特性指定的所有樣式信息,但不包含 與外部樣式表或嵌入樣式表經(jīng)層疊而來(lái)的樣式。
我們經(jīng)常使用的通過(guò)HTMLElement.style屬性就是返回來(lái)CSSStyleDeclaration對(duì)象。CSSStyleDeclaration對(duì)象表示一個(gè)元素的style屬性。
第二部分:CSSStyleSheet類型接口介紹
2.1 StyleSheet 類型支持的屬性和方法:
CSSStyleSheet 繼承自StyleSheet,StyleSheet作為一個(gè)基礎(chǔ)接口來(lái)定義非 CSS 樣式表。從 ,StyleSheet接口繼承而來(lái)的屬性如下:
-
disabled:表示樣式表是否被禁用的布爾值。這個(gè)屬性是可讀/寫(xiě)的,將這個(gè)值設(shè)置為 true 可 以禁用樣式表。 -
href:如果樣式表是通過(guò)<link>包含的,則是樣式表的 URL;否則,是 null。 -
media: -
ownerNode:指向擁有當(dāng)前樣式表的節(jié)點(diǎn)的指針,樣式表可能是在 HTML 中通過(guò)link(HTMLLinkElement)或style(HTMLStyleElement)引入的。如果當(dāng)前樣式表是其他樣式表通過(guò)@import 導(dǎo)入的,則這個(gè)屬性值為 null。IE 不支持這個(gè)屬性。 -
parentStyleSheet:在當(dāng)前樣式表是通過(guò)@import導(dǎo)入的情況下,這個(gè)屬性是一個(gè)指向?qū)胨臉邮奖淼闹羔?,否則為null。 -
title: ownerNode 中 title 屬性的值,否則為null。 -
type:表示樣式表類型的字符串。對(duì) CSS 樣式表而言,這個(gè)字符串是"type/css"。
CSSStyleSheet對(duì)象則是一 套只讀的接口。除了disabled屬性之外。
2.2 CSSStyleSheet 接口類型支持的屬性和方法:
CSSStyleSheet除了繼承StyleSheet接口的屬性之外,而且還支持下列屬性和方法:
-
cssRules(rules):樣式表中包含的樣式規(guī)則的集合。IE 不支持這個(gè)屬性,但有一個(gè)類似的rules屬性。 -
ownerRule:如果樣式表是通過(guò)@import導(dǎo)入的,這個(gè)屬性就是一個(gè)指針,指向表示導(dǎo)入的規(guī)
則;否則,值為 null。IE 不支持這個(gè)屬性。 -
deleteRule(index):刪除cssRules集合中指定位置的規(guī)則。IE 不支持這個(gè)方法,但支持
一個(gè)類似的removeRule()方法。 -
insertRule(rule,index):向cssRules集合中指定的位置插入rule字符串。IE 不支持這
個(gè)方法,但支持一個(gè)類似的addRule()方法。 -
replace():構(gòu)建一個(gè)樣式表,不允許外部引用。 -
replaceSync():構(gòu)建一個(gè)樣式表,允許外部引用。
2.3 使用JavaScript訪問(wèn)樣式表
訪問(wèn)樣式表方式一
應(yīng)用于文檔的所有樣式表是通過(guò)document.styleSheets集合來(lái)表示的。通過(guò)這個(gè)集合的 length屬性可以獲知文檔中樣式表的數(shù)量,而通過(guò)方括號(hào)語(yǔ)法或 item()方法可以訪問(wèn)每一個(gè)樣式表。
let sheet = null;
for(let i = 0, len = document.styleSheets.length;i < len; i++) {
sheet = document.styleSheets[i];
console.log(sheet.href)
}
以上代碼可以輸出文檔中使用的每一個(gè)樣式表的 href 屬性(style元素包含的樣式表沒(méi)有 href 屬性)。
訪問(wèn)樣式表方式二
還可以通過(guò)link或style元素取得CSSStyleSheet對(duì)象。DOM規(guī)定了一個(gè)包含CSSStyleSheet 對(duì)象的屬性,名叫sheet。除了 IE,其他瀏覽器都支持這個(gè)屬性。IE 支持的是styleSheet屬性。
在不同瀏覽器中都能取得樣式表對(duì)象:
function getStyleSheet(element){
return element.sheet || element.styleSheet;
}
//取得第一個(gè)<link/>元素引入的樣式表,如果沒(méi)有則返回空的HTMLCollection集合
const link = document.getElementsByTagName("link")[0];
if(typeof link === 'object' && link.rel === 'stylesheet') {
const sheet = getStyleSheet(link);
}
如果
link標(biāo)簽不是引入的css樣式,則sheet返回null。
第三部分:CSSRule規(guī)則類型接口介紹
CSSRule對(duì)象表示樣式表中的每一條規(guī)則。實(shí)際上,CSSRule是一個(gè)供其他多種類型繼承的基類 型,其中最常見(jiàn)的就是CSSStyleRule類型,表示樣式信息(其他規(guī)則還有@import、@font-face、 @page和@charset,但這些規(guī)則很少有必要通過(guò)腳本來(lái)訪問(wèn))。CSSStyleRule 對(duì)象包含下列屬性。
-
cssText:返回整條規(guī)則對(duì)應(yīng)的文本。由于瀏覽器對(duì)樣式表的內(nèi)部處理方式不同,返回的文本 可能會(huì)與樣式表中實(shí)際的文本不一樣;Safari始終都會(huì)將文本轉(zhuǎn)換成全部小寫(xiě)。IE 不支持這個(gè) 屬性。 -
parentRule:如果當(dāng)前規(guī)則是導(dǎo)入的規(guī)則,這個(gè)屬性引用的就是導(dǎo)入規(guī)則;否則,這個(gè)值為 null。IE 不支持這個(gè)屬性。 -
parentStyleSheet:當(dāng)前規(guī)則所屬的樣式表。IE 不支持這個(gè)屬性。 -
selectorText:返回當(dāng)前規(guī)則的選擇符文本。 -
style:一個(gè)CSSStyleDeclaration對(duì)象,可以通過(guò)它設(shè)置和取得規(guī)則中特定的樣式值。 -
type:表示規(guī)則類型的常量值。對(duì)于樣式規(guī)則,這個(gè)值是 1。IE 不支持這個(gè)屬性。 -
styleMap:一個(gè)StylePropertyMap對(duì)象。StylePropertyMap對(duì)象提供了CSS聲明塊的表示,該聲明塊可以替代CSSStyleDeclaration。
CSSStyleRule對(duì)象的cssText屬性與style.cssText屬性類似,但并不相同。前者包含選擇符文本和圍繞樣式信息的花括號(hào),后者只包含樣式信息(類似于 元素的 style.cssText)。此外,cssText 是只讀的,而style.cssText也可以被重寫(xiě)。
下面是獲取各個(gè)屬性顯示的結(jié)果:
<style type="text/css">
.demo {
background-color: blue;
width: 100px;
height: 200px;
}
</style>
<script>
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules;
var rule = rules[0];
console.log(rule.selectorText); //.demo
console.log(rule.style.backgroundColor); //blue
console.log(rule.style.width); //100px
console.log(rule.style.height); //200px
//.demo { background-color: blue; width: 100px; height: 200px; }
console.log(rule.cssText);
//background-color: blue; width: 100px; height: 200px;
console.log(rule.style.cssText);
</script>
使用rule.style這種方式,可以像確定元素的行內(nèi)樣式信息一樣,確定與規(guī)則相關(guān)的樣式信息。與使用元素的方式一樣,在這種方式下也可以修改樣式信息,如下面的例子:
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules;
var rule = rules[0];
rule.style.backgroundColor = "red";
以上面這種方式修改規(guī)則會(huì)影響頁(yè)面中適用于該規(guī)則的所有元素。換句話說(shuō),如果有兩個(gè)帶有demo類的div元素,那么這兩個(gè)元素都會(huì)應(yīng)用修改后的樣式。
3.1 創(chuàng)建規(guī)則和刪除規(guī)則(CSSStyleSheet接口的方法)
創(chuàng)建規(guī)則
DOM 規(guī)定,要向現(xiàn)有樣式表中添加新規(guī)則,需要使用insertRule()方法。這個(gè)方法接受兩個(gè)參 數(shù):規(guī)則文本和表示在哪里插入規(guī)則的索引。
var sheet = document.styleSheets[0];
sheet.insertRule("body { background-color: silver }", 0); //IE不支持
IE8 及更早版本支持一個(gè)類似的方法,名叫 addRule()
sheet.addRule("body", "background-color: silver", 0); //僅對(duì) IE 有效
以跨瀏覽器的方式向樣式表中插入規(guī)則:
//insertRule(document.styleSheets[0], "body", "background-color: silver", 0);
function insertRule(sheet, selectorText, cssText, position){
if (sheet.insertRule){
sheet.insertRule(selectorText + "{" + cssText + "}", position);
} else if (sheet.addRule){
sheet.addRule(selectorText, cssText, position);
}
}
上面這個(gè)例子插入的規(guī)則會(huì)改變?cè)氐谋尘邦伾2迦氲囊?guī)則將成為樣式表中的第一條規(guī)則(插入到了 位置 0)——規(guī)則的次序在確定層疊之后應(yīng)用到文檔的規(guī)則時(shí)至關(guān)重要。
刪除規(guī)則
從樣式表中刪除規(guī)則的方法是 deleteRule(),這個(gè)方法接受一個(gè)參數(shù):要?jiǎng)h除的規(guī)則的位置。例 如,要?jiǎng)h除樣式表中的第一條規(guī)則。
sheet.deleteRule(0);
IE 支持的類似方法叫 removeRule():
sheet.removeRule(0); //僅對(duì) IE 有效
以跨瀏覽器的方式向樣式表中刪除規(guī)則:
//deleteRule(document.styleSheets[0], 0);
function deleteRule(sheet, index){
if (sheet.deleteRule){
sheet.deleteRule(index);
} else if (sheet.removeRule){
sheet.removeRule(index);
}
}
添加規(guī)則和刪除規(guī)則在實(shí)際
Web開(kāi)發(fā)中并不常用,慎重使用。
第四部分:CSSStyleDeclaration 直接訪問(wèn)元素的樣式
任何支持 style 特性的 HTML 元素在 JavaScript 中都有一個(gè)對(duì)應(yīng)的 style 屬性。就是我們平常在HTML元素里寫(xiě)的樣式:
<div style="font-size:20px;color:red;">容器</div>
上面這個(gè) style 對(duì)象 是 CSSStyleDeclaration 的實(shí)例。包含著通過(guò) HTML 的 style 特性指定的所有樣式信息,但不包含與外部樣式表或嵌入樣式表經(jīng)層疊而來(lái)的樣式。
對(duì)于使用短劃線(分隔不同的詞匯,例如 background-image)的 CSS 屬性 名,必須將其轉(zhuǎn)換成駝峰大小寫(xiě)形式。下面是幾個(gè)例子:
| CSS屬性 | JavaScript屬性 |
|---|---|
background-image |
style.backgroundImage |
color |
style.color |
font-family |
style.fontFamily |
var myDiv = document.getElementById("myDiv");
myDiv.style.backgroundColor = "red";
myDiv.style.width = "100px";
myDiv.style.border = "1px solid black";
其中一個(gè)不能直接轉(zhuǎn)換的 CSS屬性 就是 float。由于 float 是 JavaScript 中的保留字,因此不能用作屬性名。DOM2 級(jí)樣式”規(guī)范規(guī)定 樣式對(duì)象上相應(yīng)的屬性名應(yīng)該是 cssFloat。而 IE 支持的則是styleFloat。可以通過(guò)下面的方式來(lái)判斷當(dāng)前瀏覽器所支持的float:
const support = (function(){
const div = document.createElement("div");
div.style.cssText = "float:left;";
let support = {
cssFloat: !!div.style.cssFloat
}
return support;
})()
const floatReal = support.cssFloat ? 'cssFloat' : 'styleFloat';
還可以直接通過(guò)document.documentMode來(lái)判斷:
const floatReal = Number(document.documentMode) < 9 ? 'styleFloat' : 'cssFloat'
只要取得一個(gè)有效的 DOM 元素的引用,就可以隨時(shí)使用 JavaScript 為其設(shè)置樣式:
var myDiv = document.getElementById("myDiv");
myDiv.style.width = "100px";
myDiv.style.border = "1px solid black";
所有度量值都必須指定一個(gè)度量單位。下面是一個(gè)設(shè)置元素style屬性的例子:
function setStyle(element, styles) {
function is_numeric(n) {
return (n !== '' && !isNaN(parseFloat(n)) && isFinite(n));
}
Object.keys(styles).forEach(function(prop) {
var unit = '';
if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && is_numeric(styles[prop])) {
unit = 'px';
}
element.style[prop] = styles[prop] + unit;
});
}
setStyle(document.getElementById("myDiv"),{ position: 'absolute', top: 0 })
Element.style返回的只是行內(nèi)樣式,并不是該元素的全部樣式。通過(guò)樣式表設(shè)置的樣式,或者從父元素繼承的樣式,無(wú)法通過(guò)這個(gè)屬性得到。元素的全部樣式要通過(guò)window.getComputedStyle()得到。
4.1 CSSStyleDeclaration 對(duì)象的屬性和方法
-
cssText:通過(guò)它能夠訪問(wèn)到 style 特性中的 CSS 代碼,可讀寫(xiě)。 -
length:應(yīng)用給元素的CSS屬性的數(shù)量。 -
parentRule:表示 CSS 信息的 CSSRule 對(duì)象。 -
getPropertyPriority(propertyName)::如果給定的屬性使用了!important 設(shè)置,則返回
"important";否則,返回空字符串。 -
getPropertyValue(propertyName)::返回給定屬性的字符串值。 -
item(index):返回給定位置的 CSS 屬性的名稱。 -
removeProperty(propertyName):從樣式中刪除給定屬性。 -
setProperty(propertyName,value,priority):將給定屬性設(shè)置為相應(yīng)的值,并加上優(yōu)先
權(quán)標(biāo)志("important"或者一個(gè)空字符串)。
cssText詳解
通過(guò)cssText屬性可以訪問(wèn) style 特性中的 CSS 代碼。在讀取模式下,cssText 返回瀏覽器對(duì) style特性中 CSS 代碼的內(nèi)部表示。在寫(xiě)入模式下,賦給 cssText 的值會(huì)重寫(xiě)整個(gè) style 特性的值;也就是說(shuō),以前通過(guò) style 特性指定的樣式信息都將丟失。例如,如果通過(guò) style 特性為元素設(shè)置了邊框,然后再以不包含邊框的規(guī)則重寫(xiě) cssText,那么就會(huì)抹去元素上的邊框。
<div id="demo" style="border:5px solid red;">容器</div>
var myDiv = document.getElementById("myDiv");
myDiv.style.cssText = "background-color: green";
console.log(myDiv.style.cssText) //background-color: green;
設(shè)置
cssText是為元素應(yīng)用多項(xiàng)變化最快捷的方式,因?yàn)榭梢砸淮涡缘貞?yīng)用所有變化。
length屬性,item()方法, getPropertyValue()方法,removeProperty()方法
設(shè)計(jì) length 屬性的目的,就是將其與 item()方法配套使用,以便迭代在元素中定義的 CSS 屬性。 在使用 length 和 item()時(shí),style 對(duì)象實(shí)際上就相當(dāng)于一個(gè)集合:
<div id="demo" style="width:100px;font-size:22px;">容器</div>
const myDiv = document.getElementById('demo');
for(let i = 0; i < myDiv.style.length; i++) {
//或者使用myDiv.style.item(i)
console.log(myDiv.style[i]) //width font-size
}
使用方括號(hào)語(yǔ)法或item()方法,都可以取得 CSS 屬性名("background-color", 不是"backgroundColor")。然后,就可以在 getPropertyValue()中使用取得的屬性名進(jìn)一步取得 屬性的值。
<div id="demo" style="width:100px;font-size:22px;">容器</div>
const myDiv = document.getElementById('demo');
var prop, value, i, len;
for (i=0, len= myDiv.style.length; i < len; i++){
prop = myDiv.style[i];
value = myDiv.style.getPropertyValue(prop);
console.log(prop + ':' + value); //width:100px font-size:22px
}
要從元素的樣式中移除某個(gè) CSS 屬性,需要使用 removeProperty()方法。使用這個(gè)方法移除一 個(gè)屬性,意味著將會(huì)為該屬性應(yīng)用默認(rèn)的樣式(從其他樣式表經(jīng)層疊而來(lái))。例如,要移除通過(guò) style 特性設(shè)置的 font-size 屬性:
<div id="demo" style="width:100px;font-size:22px;">容器</div>
const myDiv = document.getElementById('demo');
myDiv.style.removeProperty("font-size");
只要移除相應(yīng)的屬性,就可以為元素應(yīng)用默認(rèn)值。
4.2 getComputedStyle() 獲得計(jì)算的樣式
雖然 style 對(duì)象能夠提供支持 style 特性的任何元素的樣式信息,但它不包含那些從其他樣式表 層疊而來(lái)并影響到當(dāng)前元素的樣式信息。
“DOM2 級(jí)樣式”增強(qiáng)了 document.defaultView,提供了 getComputedStyle()方法。這個(gè)方法接受兩個(gè)參數(shù):要取得計(jì)算樣式的元素和一個(gè)偽元素字符串(例 如":after")。如果不需要偽元素信息,第二個(gè)參數(shù)可以是 null。getComputedStyle()方法返回一個(gè) 實(shí)時(shí)的CSSStyleDeclaration對(duì)象,當(dāng)元素的樣式更改時(shí),它會(huì)自動(dòng)更新本身。其中包含當(dāng)前元素的所有計(jì)算的樣式。
其實(shí)
window.getComputedStyle()也可以獲得元素的CSSStyleDeclaration對(duì)象。document.defaultView.getComputedStyle()和window.getComputedStyle()區(qū)別,請(qǐng)參考: MDN這篇文章。
下面代碼通過(guò) window.getComputedStyle()獲取元素樣式:
<style type="text/css">
.demo {
background-color: blue;
width: 100px;
height: 200px;
}
</style>
<div id="demo" style="background-color: red; border: 5px solid black;">容器</div>
<script>
const myDemo = document.getElementById('demo');
const computedStyle = window.getComputedStyle(myDemo,null);
console.log(computedStyle.backgroundColor); //rgb(255, 0, 0)
console.log(computedStyle.width); //100px
console.log(computedStyle.height); //200px
console.log(computedStyle.border); //5px solid rgb(0, 0, 0)
</script>
上面打印出的背景顏色不是"blue",因?yàn)檫@個(gè)樣式在自身的 style 特性中已經(jīng)被覆蓋了。
邊框?qū)傩钥赡?會(huì)也可能不會(huì)返回樣式表中實(shí)際的 border 規(guī)則。因?yàn)樵O(shè)置這種屬性(綜合屬性)實(shí)際上會(huì)涉及 很多其他屬性。在設(shè)置 border 時(shí),實(shí)際上是設(shè)置了四個(gè)邊的邊框?qū)挾?、顏色、樣式屬?br>
( border-left-width 、 border-top-color 、 border-bottom-style等等)。 因 此,即使 computedStyle.border不會(huì)在所有瀏覽器中都返回值,但具體到computedStyle.borderLeftWidth會(huì) 返回值。
IE 不支持getComputedStyle()方法,但它有一種類似的概念。在 IE 中,每個(gè)具有style屬性 的元素還有一個(gè)currentStyle屬性。這個(gè)屬性是CSSStyleDeclaration的實(shí)例。下面是一個(gè)兼容模式的例子:
function getStyles(elem) {
window.getComputedStyle ? window.getComputedStyle(elem,null) : elem.currentStyle;
}
var myDemo = document.getElementById('demo');
var computedStyle = getStyles(myDemo)
所有計(jì)算的樣式都是只讀的。不能修改計(jì)算后樣式對(duì)象中的 CSS 屬性。
第五部分:實(shí)例
5.1 設(shè)置style樣式
const ieVersion = Number(document.documentMode);
/**
* 將:-_等變成駝峰式,如foo-bar變成fooBar
* @param name 要處理的字符串
* @returns {*} 處理后的字符串
*/
const camelCase = function(name) {
return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
// 開(kāi)頭的不大寫(xiě),其余的大寫(xiě)
return offset ? letter.toUpperCase() : letter;
}).replace(/^moz([A-Z])/, 'Moz$1'); // 對(duì)moz進(jìn)行特殊處理
};
/**
* 設(shè)置元素的樣式
* @param element 要設(shè)置的元素
* @param styleName 要設(shè)置的樣式
* @param value 要設(shè)置的值
*/
function setStyle(element, styleName, value) {
if (!element || !styleName) return;
// 如果是對(duì)象則拆分后依次設(shè)置
if (typeof styleName === 'object') {
for (var prop in styleName) {
if (styleName.hasOwnProperty(prop)) {
setStyle(element, prop, styleName[prop]);
}
}
} else {
styleName = camelCase(styleName);
// opacity特殊處理
if (styleName === 'opacity' && ieVersion < 9) {
element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')';
} else {
element.style[styleName] = value;
}
}
};
5.2 獲得style樣式
var ieVersion = Number(document.documentMode);
/**
* 將:-_等變成駝峰式,如foo-bar變成fooBar
* @param name 要處理的字符串
* @returns {*} 處理后的字符串
*/
const camelCase = function(name) {
return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
// 開(kāi)頭的不大寫(xiě),其余的大寫(xiě)
return offset ? letter.toUpperCase() : letter;
}).replace(/^moz([A-Z])/, 'Moz$1'); // 對(duì)moz進(jìn)行特殊處理
};
/**
* 獲取樣式,分IE9以下和其他兩種方式處理
* @type {Function}
* @param element 要獲取樣式的元素
* @param styleName 要獲取的樣式名
*/
var getStyle = ieVersion < 9 ? function(element, styleName) {
if (!element || !styleName) return null;
// 將樣式名轉(zhuǎn)成駝峰式
styleName = camelCase(styleName);
// float特殊處理
if (styleName === 'float') {
styleName = 'styleFloat';
}
try {
// opacity特殊處理
switch (styleName) {
case 'opacity':
try {
return element.filters.item('alpha').opacity / 100;
} catch (e) {
return 1.0;
}
default:
return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null);
}
} catch (e) {
return element.style[styleName];
}
} : function(element, styleName) {
if (!element || !styleName) return null;
styleName = camelCase(styleName);
if (styleName === 'float') {
styleName = 'cssFloat';
}
try {
var computed = document.defaultView.getComputedStyle(element, '');
return element.style[styleName] || computed ? computed[styleName] : null;
} catch (e) {
return element.style[styleName];
}
};
5.3 增加和刪除class樣式
/**
* 判斷是否包含某類
* @param el 要檢測(cè)的元素
* @param cls 要檢測(cè)的類名
* @returns {boolean}
*/
function hasClass(el, cls) {
if (!el || !cls) return false;
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
if (el.classList) {
return el.classList.contains(cls);
} else {
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
};
/**
* 給元素添加某些類
* @param el 要處理的元素
* @param cls 要添加的類
*/
function addClass(el, cls) {
if (!el) return;
var curClass = el.className;
var classes = (cls || '').split(' ');
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.add(clsName);
} else if (!hasClass(el, clsName)) {
curClass += ' ' + clsName;
}
}
if (!el.classList) {
el.className = curClass;
}
};
/**
* 給元素移除某些類
* @param el 要處理的元素
* @param cls 要移除的類
*/
function removeClass(el, cls) {
if (!el || !cls) return;
var classes = cls.split(' ');
var curClass = ' ' + el.className + ' ';
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.remove(clsName);
} else if (hasClass(el, clsName)) {
curClass = curClass.replace(' ' + clsName + ' ', ' ');
}
}
if (!el.classList) {
el.className = trim(curClass);
}
};
參考鏈接
JavaScript高級(jí)程序設(shè)計(jì)(第3版)
JavaScript DOM高級(jí)程序設(shè)計(jì)
https://github.com/ElemeFE/element/blob/dev/src/utils/dom.js