通過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標簽為</h1>
</div>

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

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

<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>標簽引用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>

變綠了之后,就無法變紅艺栈。這是因為style.的方式優(yōu)先級更高湿右。

0吭狡、訪問style屬性

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

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

  • cssText :可讀寫贼急,訪問/修改內(nèi)聯(lián)樣式的字符串值太抓,與ele.geAttribute('style')的值相同走敌。
  • length :元素的 css 屬性的數(shù)量逗噩,注意捶障,某些 css 樣式是多種樣式的簡寫残邀,如 "background" 其實包含 "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,因為style應(yīng)被當成是只讀的(盡管Firefox(Gecko), Chrome 和 Opera允許修改它),這是因為通過style屬性返回的CSSStyleDeclaration對象是只讀的。

但是style屬性本身的屬性夠用來設(shè)置樣式。此外,通過單獨的樣式屬性(如elt.style.color = '...')比用`elt.style.cssText = '...' 或者 elt.setAttribute('style', '...')形式更加簡便吼具,除非你希望完全通過一個單獨語句來設(shè)置元素的全部樣式陡蝇,因為通過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),但是名字需要用駝峰命名的方式進行改變翼闹,比如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直接粘貼進去就可以了洛勉。

注意: 兩個參數(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>點擊按鈕移除 DIV 元素中的 "mystyle" 類.</p>
<button onclick="myFunction()">點我</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> 標簽目木,引入新的樣式

我們可以先在元素上定義好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> 標簽剃执,引入新的樣式

我們可以先在外部創(chuàng)建一個CSS文件柄冲,然后通過JS創(chuàng)建<link><link> 標簽,在頁面里引入新的樣式忠蝗,這個方法和 上面的創(chuàng)建 <style><style> 標簽 的方法很類似现横。
外部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é)點加載的樣式表和<style>節(jié)點內(nèi)嵌的樣式表戒祠。
document對象的styleSheets屬性,可以返回當前頁面的所有StyleSheet對象(即所有樣式表)速种。它是一個類似數(shù)組的對象姜盈。


image.png

insertRule方法用于在當前樣式表的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() 方法的實現(xiàn)原理纳寂,看http://www.111cn.net/wy/jquery/97254.htm
今天我們也簡單的實現(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)實現(xiàn)了我們要的功能了,其中判斷是否為DOM元素的那部分還可以繼續(xù)提出來作為一個單獨的方法陆错,其中修改元素css的部分灯抛,是通過修改元素的style對象的cssText屬性,這種辦法修改css的優(yōu)先級很高音瓷,和直接寫內(nèi)聯(lián)樣式一樣对嚼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市绳慎,隨后出現(xiàn)的幾起案子纵竖,更是在濱河造成了極大的恐慌,老刑警劉巖杏愤,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件靡砌,死亡現(xiàn)場離奇詭異,居然都是意外死亡珊楼,警方通過查閱死者的電腦和手機通殃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厕宗,“玉大人贴膘,你說我怎么就攤上這事封孙∷绷” “怎么了递惋?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蛇受。 經(jīng)常有香客問我句葵,道長厕鹃,這世上最難降的妖魔是什么兢仰? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任乍丈,我火速辦了婚禮,結(jié)果婚禮上把将,老公的妹妹穿的比我還像新娘轻专。我一直安慰自己,他們只是感情好察蹲,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布请垛。 她就那樣靜靜地躺著,像睡著了一般洽议。 火紅的嫁衣襯著肌膚如雪宗收。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天亚兄,我揣著相機與錄音混稽,去河邊找鬼。 笑死审胚,一個胖子當著我的面吹牛匈勋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播膳叨,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼洽洁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了菲嘴?” 一聲冷哼從身側(cè)響起饿自,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎龄坪,沒想到半個月后昭雌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡悉默,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年城豁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抄课。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡唱星,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跟磨,到底是詐尸還是另有隱情间聊,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布抵拘,位于F島的核電站哎榴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尚蝌,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一迎变、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧飘言,春花似錦衣形、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至苛预,卻和暖如春句狼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背热某。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工腻菇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人苫拍。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓芜繁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绒极。 傳聞我的和親對象是個殘疾皇子骏令,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容