通過JS控制CSS

參考
簡單說 通過JS控制CSS的各種方式(上)
簡單說 通過JS控制CSS的各種方式(下)
說明
通過JS控制CSS,我們能做出更多漂亮的頁面特效,做出更炫的交互效果。今天我們來說說JS控制CSS的各種方式。

解釋
JavaScript、CSS、HTML是前端三劍客,我們說正事之前,先來說說CSS與HTML的事。

一、在HTML中使用CSS有三種方式

參考
html中使用css的三種方式
CSS 引入方式

1、內(nèi)聯(lián)方式
CSS定義在單個的HTML元素中的style屬性中

<!-- 在div 后跟style屬性,等號后面寫上css樣式 -->
<div style="background-color:#000;color:#fff;">  
  <h1>這是一個DIV標(biāo)簽為</h1>
</div>

這通常是個很糟糕的書寫方式,它只能改變當(dāng)前標(biāo)簽的樣式,如果想要多個 <div> 擁有相同的樣式,你不得不重復(fù)地為每個 <div> 添加相同的樣式,如果想要修改一種樣式,又不得不修改所有的 style 中的代碼。很顯然,內(nèi)聯(lián)方式引入 CSS 代碼會導(dǎo)致 HTML 代碼變得冗長,且使得網(wǎng)頁難以維護(hù)。

2、內(nèi)部樣式表
CSS通過<style></style>標(biāo)簽定義在HTML頁面的<head></head>標(biāo)簽中

<head>
    <meta charset="utf-8">
    <title>js測試</title>
  <!-- 內(nèi)部樣式表開始 -->
    <style >
      .box{
        background-color:#000;
        color:#fff;
      }
    <!-- 內(nèi)部樣式表結(jié)束 -->
    </style>
  </head>

  <body>
    <div class="box">
      <h1>這是一個DIV</h1>
    </div>
  </body>

3、外部樣式表
將CSS定義在一個外部的CSS文件中,在HTML頁面通過<link></link>標(biāo)簽引用CSS文件

<link rel="stylesheet" type="text/css"  href="./css/layout.css" > <!--href中寫css樣式表存放的路徑-->
二、JS控制CSS(注意以下方式會按優(yōu)先級從高到低排序)

我們用JS控制CSS,我們還是要考慮css優(yōu)先級的問題,為了能讓設(shè)置后的css起作用,我們還是選擇優(yōu)先級高的方法比較好。

優(yōu)先級

關(guān)于優(yōu)化級測試,參考JavaScript中的style和className

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #div1{
            width: 200px;
            height: 200px;
            border: 1px solid black;
        }
        .box{
            background: red;
        }
    </style>
    <script>
        function toRed() {
            var Div = document.getElementById('div1');
            Div.className='box';
        }
 
        function toGreen() {
            var Div = document.getElementById('div1');
            Div.style.background='green';
 
        }
    </script>
</head>
<body>
<input type="button" value="變紅"onclick="toRed()">
<input type="button" value="變綠"onclick="toGreen()">
 
 
<div id="div1"></div>
</body>
</html>

變綠了之后,就無法變紅。這是因?yàn)閟tyle.的方式優(yōu)先級更高。

0、訪問style屬性

任何支持 style 特性的 HTML 元素在 JavaScript 中都有一個對應(yīng)的 style 屬性。這個 style 對象是 CSSStyleDeclaration 的實(shí)例,只包含所有內(nèi)聯(lián)樣式。

style 對象除了 css 樣式屬性外,還包含如下屬性和方法:

  • cssText :可讀寫,訪問/修改內(nèi)聯(lián)樣式的字符串值,與ele.geAttribute('style')的值相同。
  • length :元素的 css 屬性的數(shù)量,注意,某些 css 樣式是多種樣式的簡寫,如 "background" 其實(shí)包含 "background-image" 等樣式,而此屬性獲取到的數(shù)量是非簡寫的數(shù)量。
  • getPropertyPriority(propertyName) :獲取 css 屬性的優(yōu)先級字符。即該樣式設(shè)置了 "!important" 則返回 "important" ;否則返回空字符。
  • getPropertyValue(propertyName) :獲取 css 屬性的值。
  • removeProperty(propertyName) :移除指定 css 屬性。
  • setProperty(propertyName, value, priority) :設(shè)置指定 css 屬性的值和優(yōu)先級,priority 為空字符則表示不設(shè)置優(yōu)先級。

可以看以下例子:

// 獲取指定元素
let ele = document.getElementById('myDiv');
// 獲取元素的 style 屬性
let styl = ele.style;
console.log(styl.cssText);    // "background: red; color: green;"
// 修改字體大小為 "18px" , 注意要使用駝峰式
styl.fontSize = '18px';
// 設(shè)置 background 樣式,并添加"優(yōu)先級字符"
styl.setProperty('background', 'blue', 'important');
console.log(styl.getPropertyPriority('background'));    // "important"
console.log(styl.getPropertyValue('background'));       // "blue"
// 移除 "color" 樣式
styl.removeProperty('color');
console.log(styl.cssText);              // "background: blue !important; font-size: 18px;"
console.log(ele.getAttribute('style')); // "background: blue !important; font-size: 18px;"
console.log(styl.length);               // 11
// 修改 cssText 屬性
styl.cssText = ""
console.log(styl.cssText);              // ""

參考https://developer.mozilla.org/zh-CN/docs/Web/API/ElementCSSInlineStyle/style
**HTMLElement.style** 屬性返回一個 CSSStyleDeclaration 對象,表示元素的 內(nèi)聯(lián)style 屬性(attribute),但忽略任何樣式表應(yīng)用的屬性。 通過 style 可以訪問的 CSS 屬性列表,可以查看 CSS Properties Reference

由于 style 屬性的優(yōu)先級和通過style設(shè)置內(nèi)聯(lián)樣式是一樣的,并且在css層級樣式中擁有最高優(yōu)先級,因此在為特定的元素設(shè)置樣式時很有用。

注意不能通過直接給style屬性設(shè)置字符串(如:elt.style = "color: blue;")來設(shè)置style,因?yàn)閟tyle應(yīng)被當(dāng)成是只讀的(盡管Firefox(Gecko), Chrome 和 Opera允許修改它),這是因?yàn)橥ㄟ^style屬性返回的CSSStyleDeclaration對象是只讀的。

但是style屬性本身的屬性夠用來設(shè)置樣式。此外,通過單獨(dú)的樣式屬性(如elt.style.color = '...')比用`elt.style.cssText = '...' 或者 elt.setAttribute('style', '...')形式更加簡便,除非你希望完全通過一個單獨(dú)語句來設(shè)置元素的全部樣式,因?yàn)橥ㄟ^style本身屬性設(shè)置的樣式不會影響到通過其他方式設(shè)置的其他css屬性的樣式。

// 在單個語句中設(shè)置多個樣式
elt.style.cssText = "color: blue; border: 1px solid black";
// 或者
elt.setAttribute("style", "color:red; border: 1px solid blue;");

// 設(shè)置特定樣式,同時保持其他內(nèi)聯(lián)樣式值不變
elt.style.color = "blue";
1、通過“ . ”直接設(shè)置元素的style屬性

語法:

element.style.attributename= attributevalue;

例如:

document.body.style.width = '100px';    

注意:這里的style屬性的值是一個對象。 這個對象所包含的屬性與CSS規(guī)則一 一對應(yīng),但是名字需要用駝峰命名的方式進(jìn)行改變,比如background-color寫成backgroundColor。改寫的規(guī)則是將橫杠從CSS屬性名中去除,然后將橫杠后的第一個字母大寫。如果CSS屬性名是JavaScript保留字,則規(guī)則名之前需要加上字符串css,比如float寫成cssFloat。

document.body.style.backgroundColor= 'red';  

溫馨提示: 如果你不愿意換成駝峰命名法的話,也有辦法,用“[ ]”代替 “.” , “[ ]” 中直接寫字符串類型的CSS屬性。
例如:

document.body.style['background-color']= 'red';  

如果你好奇為什么可以這樣做,請看簡單說 background-color 與 backgroundColor的區(qū)別

2、通過 setAttribute 方法 設(shè)置元素的style屬性

setAttribute 方法添加指定的屬性,并為其賦指定的值。
如果這個指定的屬性已存在,則僅設(shè)置/更改值。

語法:

element.setAttribute(attributename,attributevalue)

例如:

var a = document.body;
a.setAttribute("style","background-color:red;height:100px;");    

這個方法很好用,第一個參數(shù)寫“style”,第二個參數(shù)就是CSS,把需要的CSS直接粘貼進(jìn)去就可以了。

注意: 兩個參數(shù)都是字符串類型的哦!

3、通過style對象的 setProperty 方法 設(shè)置CSS屬性

setProperty 方法直接設(shè)置某個CSS屬性

語法:

element.style.setProperty (propertyName, propertyValue, priority);

setProperty 方法的第三個參數(shù)(priority),字符串類型,指定樣式屬性的優(yōu)先級。樣式屬性的優(yōu)先級可以通過getPropertyPriority方法獲取。
如果要設(shè)置!important,建議設(shè)置第三個參數(shù) ,但是傳參的時候不用寫前面的 “!” 。
例如:

var a = document.body;
a.style.setProperty ("background-color", "green", 'important');

注意: setProperty 方法 與 setAttribute 方法 是不一樣的,setProperty 方法是元素style屬性的一個方法,setAttribute 方法是元素的一個方法,雖然他們都能控制CSS,但還是有區(qū)別的。

更多關(guān)于setProperty 方法的知識請看
http://help.dottoro.com/ljdpsdnb.php

4、通過style對象的cssText屬性,控制CSS

style對象 的 cssText屬性設(shè)置或返回樣式聲明的內(nèi)容作為字符串。

語法:

element.style.cssText = string

例如:

document.body.style.cssText = "background-color:red";

注意: 直接用 “=” 會覆蓋原來的值,需要追加新的值就用 “+=”

5、通過元素的 className 屬性 控制CSS

我們可以通過先定義好class,然后改變元素的class屬性,來控制CSS

元素的 className 屬性設(shè)置或返回元素的 class 屬性值。

語法:

element.className = 'className';   

例如:

<!doctype html>
<html lang="zh">
 <head>
     <meta charset="utf-8">
     <style>
        .redBorder{
            border:1px solid red;
        }
        .greenBg{
            background-color:green;
        }
     </style>
 </head>

 <body class="redBorder">
 </body>

 <script>
    var a = document.body;
    a.className = 'greenBg';
    //元素的redBorder class會被替換 為 greenBg
    //如果兩個class 都需要,可以把+ 變成 += ,值的最前面加上一個空格,像下面這樣
    //a.className += ' greenBg';
 </script>
</html>

類似的還有classlist

  • classList 屬性返回元素的類名,作為 DOMTokenList 對象。
  • 該屬性用于在元素中添加,移除及切換 CSS 類。
  • classList 屬性是只讀的,但你可以使用 add() 和 remove() 方法修改它。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
<style>
.mystyle {
    width: 300px;
    height: 50px;
    background-color: coral;
    color: white;
    font-size: 25px;
}
</style>
</head>
<body>

<p>點(diǎn)擊按鈕移除 DIV 元素中的 "mystyle" 類.</p>
<button onclick="myFunction()">點(diǎn)我</button>
<p><strong>注意:</strong> Internet Explorer 9 及更早 IE 版本瀏覽器不支持 classList 屬性。</p>
<div id="myDIV" class="mystyle">
我是一個 DIV 元素。
</div>
<script>
function myFunction() {
    document.getElementById("myDIV").classList.remove("mystyle");
}
</script>

</body>
</html>
6、通過創(chuàng)建 <style><style> 標(biāo)簽,引入新的樣式

我們可以先在元素上定義好class屬性,然后通過JS創(chuàng)建<style></style>,給元素加上樣式

例如:

<!doctype html>
<html lang="zh">
 <head>
     <meta charset="utf-8">
 </head>

 <body class="redBg">
 </body>

 <script>
    var head = document.head;
    // 創(chuàng)建 style 元素
    var styleElement = document.createElement('style');
    
    //在創(chuàng)建好的style元素中,寫上CSS
    styleElement.innerHTML = '.redBg{background-color:red;}';
    //在head 中加上 style 元素
    head.append(styleElement);
 </script>
</html>

7、通過創(chuàng)建 <link><link> 標(biāo)簽,引入新的樣式

我們可以先在外部創(chuàng)建一個CSS文件,然后通過JS創(chuàng)建<link><link> 標(biāo)簽,在頁面里引入新的樣式,這個方法和 上面的創(chuàng)建 <style><style> 標(biāo)簽 的方法很類似。
外部CSS文件(style.css):

.redBg{
    background-color:red;
}

HTML頁面:

<!doctype html>
<html lang="zh">
 <head>
     <meta charset="utf-8">
 </head>

 <body class="redBg">
 </body>

 <script>
    // 創(chuàng)建 link 元素
    var linkElement = document.createElement('link');
    
    //設(shè)置 linkElement 的src 為外部CSS文件的路徑
     linkElement.href = './style.css';
     
    //在head 中加上 linkElement 元素
    document.head.append(linkElement);
 </script>
</html>

8、通過 insertRule 或者 addRule 插入新的樣式

StyleSheet對象代表網(wǎng)頁的一張樣式表,它包括<link>節(jié)點(diǎn)加載的樣式表和<style>節(jié)點(diǎn)內(nèi)嵌的樣式表。
document對象的styleSheets屬性,可以返回當(dāng)前頁面的所有StyleSheet對象(即所有樣式表)。它是一個類似數(shù)組的對象。


image.png

insertRule方法用于在當(dāng)前樣式表的cssRules對象插入CSS規(guī)則
語法:

stylesheet.insertRule(rule, index)

insertRule 方法的第一個參數(shù)是表示CSS規(guī)則的字符串,第二個參數(shù)是該規(guī)則在cssRules對象的插入位置。

例如:

var styleTag = document.createElement ("style");
var head = document.getElementsByTagName ("head")[0];
head.appendChild (styleTag);

styleTag.sheet.insertRule ("body {background:red;}", 0);

更多關(guān)于insertRule 方法的知識請看
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule

addRule方法
語法:

object.addRule (selector, styleDef [, positionIndex]);

參數(shù)說明:
selector : 必須,指定新規(guī)則對象的選擇器的字符串。
styleDef : 必須,指定新規(guī)則對象的樣式定義的字符串。
positionIndex :可選,整數(shù),指定規(guī)則集合中新規(guī)則的位置。

var styleTag = document.createElement ("style");
var head = document.getElementsByTagName ("head")[0];
head.appendChild (styleTag);

styleTag.sheet.addRule ("body", "background:red", 0);

更多關(guān)于addRule 方法的知識請看
http://help.dottoro.com/ljuucnct.php

溫馨提示: 方式8,插入的新的樣式,在頁面中看不見,如果需要看見的話,可以通過樣式表的cssRules屬性。
例如:

styleTag.sheet.cssRules

三、封裝一下

我們用過的各種類庫或者框架中,經(jīng)常會使用到JS控制CSS的函數(shù),比如JQuery中的css() 方法。
想明白JQuery中的css() 方法的實(shí)現(xiàn)原理,看http://www.111cn.net/wy/jquery/97254.htm
今天我們也簡單的實(shí)現(xiàn)一下這個方法。

//需要兩個參數(shù) el,css
//el :DOM元素
//css :css規(guī)則 字符串類型
function css(el, css) {
   //el如果是DOM元素,就修改元素的css
   if (!!(el && el.nodeType == 1)) {
       //確保第二個參數(shù)是字符串類型的css規(guī)則
       if (typeof css == 'string' && css.indexOf(':') > 0) {
           //元素有style對象,然后修改style對象的cssText屬性
           el.style && (el.style.cssText += ';' + css);
       }

     //el如果不是DOM,就發(fā)出警告,結(jié)束方法
   } else {
       console.warn('css方法需要一個參數(shù),這個參數(shù)必須是DOM元素');
       return;
   }
}

上面寫的這個函數(shù),已經(jīng)實(shí)現(xiàn)了我們要的功能了,其中判斷是否為DOM元素的那部分還可以繼續(xù)提出來作為一個單獨(dú)的方法,其中修改元素css的部分,是通過修改元素的style對象的cssText屬性,這種辦法修改css的優(yōu)先級很高,和直接寫內(nèi)聯(lián)樣式一樣。

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

相關(guān)閱讀更多精彩內(nèi)容

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