學(xué)會(huì)使用JavaScript訪問(wèn)和修改CSS樣式

第一部分:接口介紹

image

首先說(shuō)在HTML中定義樣式的方式有 3 種:

  1. 通過(guò) link 元素包含外部樣式表文件
  2. 使用 style 元素定義嵌入式樣式
  3. 使用 style 特性定義針對(duì)特定元素的樣式

DOM2級(jí)模塊圍繞這三種應(yīng)用樣式機(jī)制提供了一套API。理解了這套API就理解了如何用JS操作CSS了。這套接口種類很多。如下圖:

image

可以參考MDN這篇文章了解。

接口都是有規(guī)律的,死記硬背不好記住,根據(jù)HTML中定義樣式的3種方式來(lái)看接口的定義,自然就更好理解。

1.1 CSSStyleSheet樣式表對(duì)象

名字中帶有StyleSheet的接口就樣式表的意思。CSSStyleSheet接口類型表示的是樣式表。包括通過(guò)link元素包含的外部樣式表和在<style type="text/css"></style>元素中定義的樣式表。CSSStyleSheet接口繼承StyleSheetStyleSheet可以作為一個(gè)基礎(chǔ)接口來(lái)定義非 CSS 樣式表。

1.2 CSSRule樣式表規(guī)則對(duì)象

名字中帶有Rule的接口就代表規(guī)則的意思。CSSRule對(duì)象表示樣式表中的每一條規(guī)則。CSSRule其實(shí) 是一個(gè)供其他多種類型繼承的基類型。其中最常用的就是 CSSStyleRule 類型,表示樣式信息。

CSSRule的所有子類型如下:

  1. CSSCharsetRule
  2. CSSConditionRule
  3. CSSCounterStyleRule
  4. CSSFontFeatureValuesRule
  5. CSSGroupingRule
  6. CSSImportRule
  7. CSSKeyframeRule
  8. CSSKeyframesRule
  9. CSSMarginRule
  10. CSSMediaRule
  11. CSSNamespaceRule
  12. CSSPageRule
  13. CSSSupportsRule
  14. CSSViewportRule
  15. CSSFontFaceRule
  16. CSSStyleRule

這些規(guī)則很少有必要通過(guò)腳本來(lái)訪問(wèn),而最常用的就是 CSSStyleRule 類型。

通過(guò)下圖可以加深對(duì)StyleSheet,CSSRule關(guān)系的理解。

image

1.3 CSSStyleDeclaration 應(yīng)用在元素style屬性的對(duì)象

任何支持style特性的HTML元素在JavaScript中都有一個(gè)對(duì)應(yīng)的style屬性。這個(gè)style對(duì)象是 CSSStyleDeclaration的實(shí)例。包含著通過(guò)HTMLstyle特性指定的所有樣式信息,但不包含 與外部樣式表或嵌入樣式表經(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ò)linkstyle元素取得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。由于 floatJavaScript 中的保留字,因此不能用作屬性名。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-widthborder-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ì)

獲取元素CSS值之getComputedStyle方法熟悉

CSS Object Model

可構(gòu)造樣式表

獲取元素CSS值之getComputedStyle方法熟悉

CSS操作

https://github.com/ElemeFE/element/blob/dev/src/utils/dom.js

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容