CSS 與 JavaScript 是兩個(gè)有著明確分工的領(lǐng)域,前者負(fù)責(zé)頁(yè)面的視覺效果,后者負(fù)責(zé)與用戶的行為互動(dòng)。但是,它們畢竟同屬網(wǎng)頁(yè)開發(fā)的前端,因此不可避免有著交叉和互相配合。本章介紹如何通過 JavaScript 操作 CSS。
HTML 元素的 style 屬性
操作 CSS 樣式最簡(jiǎn)單的方法,就是使用網(wǎng)頁(yè)元素節(jié)點(diǎn)的getAttribute()
方法、setAttribute()
方法和removeAttribute()
方法,直接讀寫或刪除網(wǎng)頁(yè)元素的style
屬性。
div.setAttribute(
'style',
'background-color:red;' + 'border:1px solid black;'
);
上面的代碼相當(dāng)于下面的 HTML 代碼。
<div style="background-color:red; border:1px solid black;" />
style
不僅可以使用字符串讀寫,它本身還是一個(gè)對(duì)象,部署了 CSSStyleDeclaration 接口(詳見下面的介紹),可以直接讀寫個(gè)別屬性。
e.style.fontSize = '18px';
e.style.color = 'black';
CSSStyleDeclaration 接口
簡(jiǎn)介
CSSStyleDeclaration 接口用來操作元素的樣式。三個(gè)地方部署了這個(gè)接口。
- 元素節(jié)點(diǎn)的
style
屬性(Element.style
) CSSStyle
實(shí)例的style
屬性window.getComputedStyle()
的返回值
CSSStyleDeclaration 接口可以直接讀寫 CSS 的樣式屬性,不過,連詞號(hào)需要變成駱駝拼寫法。
var divStyle = document.querySelector('div').style;
divStyle.backgroundColor = 'red';
divStyle.border = '1px solid black';
divStyle.width = '100px';
divStyle.height = '100px';
divStyle.fontSize = '10em';
divStyle.backgroundColor // red
divStyle.border // 1px solid black
divStyle.height // 100px
divStyle.width // 100px
上面代碼中,style
屬性的值是一個(gè) CSSStyleDeclaration 實(shí)例。這個(gè)對(duì)象所包含的屬性與 CSS 規(guī)則一一對(duì)應(yīng),但是名字需要改寫,比如background-color
寫成backgroundColor
。改寫的規(guī)則是將橫杠從 CSS 屬性名中去除,然后將橫杠后的第一個(gè)字母大寫。如果 CSS 屬性名是 JavaScript 保留字,則規(guī)則名之前需要加上字符串css
,比如float
寫成cssFloat
。
注意,該對(duì)象的屬性值都是字符串,設(shè)置時(shí)必須包括單位,但是不含規(guī)則結(jié)尾的分號(hào)。比如,divStyle.width
不能寫為100
,而要寫為100px
。
另外,Element.style
返回的只是行內(nèi)樣式,并不是該元素的全部樣式。通過樣式表設(shè)置的樣式,或者從父元素繼承的樣式,無法通過這個(gè)屬性得到。元素的全部樣式要通過window.getComputedStyle()
得到。
CSSStyleDeclaration 實(shí)例屬性
(1)CSSStyleDeclaration.cssText
CSSStyleDeclaration.cssText
屬性用來讀寫當(dāng)前規(guī)則的所有樣式聲明文本。
var divStyle = document.querySelector('div').style;
divStyle.cssText = 'background-color: red;'
+ 'border: 1px solid black;'
+ 'height: 100px;'
+ 'width: 100px;';
注意,cssText
的屬性值不用改寫 CSS 屬性名。
刪除一個(gè)元素的所有行內(nèi)樣式,最簡(jiǎn)便的方法就是設(shè)置cssText
為空字符串。
divStyle.cssText = '';
(2)CSSStyleDeclaration.length
CSSStyleDeclaration.length
屬性返回一個(gè)整數(shù)值,表示當(dāng)前規(guī)則包含多少條樣式聲明。
// HTML 代碼如下
// <div id="myDiv"
// style="height: 1px;width: 100%;background-color: #CA1;"
// ></div>
var myDiv = document.getElementById('myDiv');
var divStyle = myDiv.style;
divStyle.length // 3
上面代碼中,myDiv
元素的行內(nèi)樣式共包含3條樣式規(guī)則。
(3)CSSStyleDeclaration.parentRule
CSSStyleDeclaration.parentRule
屬性返回當(dāng)前規(guī)則所屬的那個(gè)樣式塊(CSSRule 實(shí)例)。如果不存在所屬的樣式塊,該屬性返回null
。
該屬性只讀,且只在使用 CSSRule 接口時(shí)有意義。
var declaration = document.styleSheets[0].rules[0].style;
declaration.parentRule === document.styleSheets[0].rules[0]
// true
CSSStyleDeclaration 實(shí)例方法
(1)CSSStyleDeclaration.getPropertyPriority()
CSSStyleDeclaration.getPropertyPriority
方法接受 CSS 樣式的屬性名作為參數(shù),返回一個(gè)字符串,表示有沒有設(shè)置important
優(yōu)先級(jí)。如果有就返回important
,否則返回空字符串。
// HTML 代碼為
// <div id="myDiv" style="margin: 10px!important; color: red;"/>
var style = document.getElementById('myDiv').style;
style.margin // "10px"
style.getPropertyPriority('margin') // "important"
style.getPropertyPriority('color') // ""
上面代碼中,margin
屬性有important
優(yōu)先級(jí),color
屬性沒有。
(2)CSSStyleDeclaration.getPropertyValue()
CSSStyleDeclaration.getPropertyValue
方法接受 CSS 樣式屬性名作為參數(shù),返回一個(gè)字符串,表示該屬性的屬性值。
// HTML 代碼為
// <div id="myDiv" style="margin: 10px!important; color: red;"/>
var style = document.getElementById('myDiv').style;
style.margin // "10px"
style.getPropertyValue("margin") // "10px"
(3)CSSStyleDeclaration.item()
CSSStyleDeclaration.item
方法接受一個(gè)整數(shù)值作為參數(shù),返回該位置的 CSS 屬性名。
// HTML 代碼為
// <div id="myDiv" style="color: red; background-color: white;"/>
var style = document.getElementById('myDiv').style;
style.item(0) // "color"
style.item(1) // "background-color"
上面代碼中,0
號(hào)位置的 CSS 屬性名是color
,1
號(hào)位置的 CSS 屬性名是background-color
。
如果沒有提供參數(shù),這個(gè)方法會(huì)報(bào)錯(cuò)。如果參數(shù)值超過實(shí)際的屬性數(shù)目,這個(gè)方法返回一個(gè)空字符值。
(4)CSSStyleDeclaration.removeProperty()
CSSStyleDeclaration.removeProperty
方法接受一個(gè)屬性名作為參數(shù),在 CSS 規(guī)則里面移除這個(gè)屬性,返回這個(gè)屬性原來的值。
// HTML 代碼為
// <div id="myDiv" style="color: red; background-color: white;">
// 111
// </div>
var style = document.getElementById('myDiv').style;
style.removeProperty('color') // 'red'
// HTML 代碼變?yōu)?// <div id="myDiv" style="background-color: white;">
上面代碼中,刪除color
屬性以后,字體顏色從紅色變成默認(rèn)顏色。
(5)CSSStyleDeclaration.setProperty()
CSSStyleDeclaration.setProperty
方法用來設(shè)置新的 CSS 屬性。該方法沒有返回值。
該方法可以接受三個(gè)參數(shù)。
- 第一個(gè)參數(shù):屬性名,該參數(shù)是必需的。
- 第二個(gè)參數(shù):屬性值,該參數(shù)可選。如果省略,則參數(shù)值默認(rèn)為空字符串。
- 第三個(gè)參數(shù):優(yōu)先級(jí),該參數(shù)可選。如果設(shè)置,唯一的合法值是
important
,表示 CSS 規(guī)則里面的!important
。
// HTML 代碼為
// <div id="myDiv" style="color: red; background-color: white;">
// 111
// </div>
var style = document.getElementById('myDiv').style;
style.setProperty('border', '1px solid blue');
上面代碼執(zhí)行后,myDiv
元素就會(huì)出現(xiàn)藍(lán)色的邊框。
CSS 模塊的偵測(cè)
CSS 的規(guī)格發(fā)展太快,新的模塊層出不窮。不同瀏覽器的不同版本,對(duì) CSS 模塊的支持情況都不一樣。有時(shí)候,需要知道當(dāng)前瀏覽器是否支持某個(gè)模塊,這就叫做“CSS模塊的偵測(cè)”。
一個(gè)比較普遍適用的方法是,判斷元素的style
對(duì)象的某個(gè)屬性值是否為字符串。
typeof element.style.animationName === 'string';
typeof element.style.transform === 'string';
如果該 CSS 屬性確實(shí)存在,會(huì)返回一個(gè)字符串。即使該屬性實(shí)際上并未設(shè)置,也會(huì)返回一個(gè)空字符串。如果該屬性不存在,則會(huì)返回undefined
。
document.body.style['maxWidth'] // ""
document.body.style['maximumWidth'] // undefined
上面代碼說明,這個(gè)瀏覽器支持max-width
屬性,但是不支持maximum-width
屬性。
注意,不管 CSS 屬性名的寫法帶不帶連詞線,style
屬性上都能反映出該屬性是否存在。
document.body.style['backgroundColor'] // ""
document.body.style['background-color'] // ""
另外,使用的時(shí)候,需要把不同瀏覽器的 CSS 前綴也考慮進(jìn)去。
var content = document.getElementById('content');
typeof content.style['webkitAnimation'] === 'string'
這種偵測(cè)方法可以寫成一個(gè)函數(shù)。
function isPropertySupported(property) {
if (property in document.body.style) return true;
var prefixes = ['Moz', 'Webkit', 'O', 'ms', 'Khtml'];
var prefProperty = property.charAt(0).toUpperCase() + property.substr(1);
for(var i = 0; i < prefixes.length; i++){
if((prefixes[i] + prefProperty) in document.body.style) return true;
}
return false;
}
isPropertySupported('background-clip')
// true
CSS 對(duì)象
瀏覽器原生提供 CSS 對(duì)象,為 JavaScript 操作 CSS 提供一些工具方法。
這個(gè)對(duì)象目前有兩個(gè)靜態(tài)方法。
CSS.escape()
CSS.escape
方法用于轉(zhuǎn)義 CSS 選擇器里面的特殊字符。
<div id="foo#bar">
上面代碼中,該元素的id
屬性包含一個(gè)#
號(hào),該字符在 CSS 選擇器里面有特殊含義。不能直接寫成document.querySelector('#foo#bar')
,只能寫成document.querySelector('#foo\\#bar')
。這里必須使用雙斜杠的原因是,單引號(hào)字符串本身會(huì)轉(zhuǎn)義一次斜杠。
CSS.escape
方法就用來轉(zhuǎn)義那些特殊字符。
document.querySelector('#' + CSS.escape('foo#bar'))
CSS.supports()
CSS.supports
方法返回一個(gè)布爾值,表示當(dāng)前環(huán)境是否支持某一句 CSS 規(guī)則。
它的參數(shù)有兩種寫法,一種是第一個(gè)參數(shù)是屬性名,第二個(gè)參數(shù)是屬性值;另一種是整個(gè)參數(shù)就是一行完整的 CSS 語(yǔ)句。
// 第一種寫法
CSS.supports('transform-origin', '5px') // true
// 第二種寫法
CSS.supports('display: table-cell') // true
注意,第二種寫法的參數(shù)結(jié)尾不能帶有分號(hào),否則結(jié)果不準(zhǔn)確。
CSS.supports('display: table-cell;') // false
window.getComputedStyle()
行內(nèi)樣式(inline style)具有最高的優(yōu)先級(jí),改變行內(nèi)樣式,通常會(huì)立即反映出來。但是,網(wǎng)頁(yè)元素最終的樣式是綜合各種規(guī)則計(jì)算出來的。因此,如果想得到元素實(shí)際的樣式,只讀取行內(nèi)樣式是不夠的,需要得到瀏覽器最終計(jì)算出來的樣式規(guī)則。
window.getComputedStyle
方法,就用來返回瀏覽器計(jì)算后得到的最終規(guī)則。它接受一個(gè)節(jié)點(diǎn)對(duì)象作為參數(shù),返回一個(gè) CSSStyleDeclaration 實(shí)例,包含了指定節(jié)點(diǎn)的最終樣式信息。所謂“最終樣式信息”,指的是各種 CSS 規(guī)則疊加后的結(jié)果。
var div = document.querySelector('div');
var styleObj = window.getComputedStyle(div);
styleObj.backgroundColor
上面代碼中,得到的背景色就是div
元素真正的背景色。
注意,CSSStyleDeclaration 實(shí)例是一個(gè)活的對(duì)象,任何對(duì)于樣式的修改,會(huì)實(shí)時(shí)反映到這個(gè)實(shí)例上面。另外,這個(gè)實(shí)例是只讀的。
getComputedStyle
方法還可以接受第二個(gè)參數(shù),表示當(dāng)前元素的偽元素(比如:before
、:after
、:first-line
、:first-letter
等)。
var result = window.getComputedStyle(div, ':before');
下面的例子是如何獲取元素的高度。
var elem = document.getElementById('elem-container');
var styleObj = window.getComputedStyle(elem, null)
var height = styleObj.height;
// 等同于
var height = styleObj['height'];
var height = styleObj.getPropertyValue('height');
上面代碼得到的height
屬性,是瀏覽器最終渲染出來的高度,比其他方法得到的高度更可靠。由于styleObj
是 CSSStyleDeclaration 實(shí)例,所以可以使用各種 CSSStyleDeclaration 的實(shí)例屬性和方法。
有幾點(diǎn)需要注意。
- CSSStyleDeclaration 實(shí)例返回的 CSS 值都是絕對(duì)單位。比如,長(zhǎng)度都是像素單位(返回值包括
px
后綴),顏色是rgb(#, #, #)
或rgba(#, #, #, #)
格式。 - CSS 規(guī)則的簡(jiǎn)寫形式無效。比如,想讀取
margin
屬性的值,不能直接讀,只能讀marginLeft
、marginTop
等屬性;再比如,font
屬性也是不能直接讀的,只能讀font-size
等單個(gè)屬性。 - 如果讀取 CSS 原始的屬性名,要用方括號(hào)運(yùn)算符,比如
styleObj['z-index']
;如果讀取駱駝拼寫法的 CSS 屬性名,可以直接讀取styleObj.zIndex
。 - 該方法返回的 CSSStyleDeclaration 實(shí)例的
cssText
屬性無效,返回undefined
。
CSS 偽元素
CSS 偽元素是通過 CSS 向 DOM 添加的元素,主要是通過:before
和:after
選擇器生成,然后用content
屬性指定偽元素的內(nèi)容。
下面是一段 HTML 代碼。
<div id="test">Test content</div>
CSS 添加偽元素:before
的寫法如下。
#test:before {
content: 'Before ';
color: #FF0;
}
節(jié)點(diǎn)元素的style
對(duì)象無法讀寫偽元素的樣式,這時(shí)就要用到window.getComputedStyle()
。JavaScript 獲取偽元素,可以使用下面的方法。
var test = document.querySelector('#test');
var result = window.getComputedStyle(test, ':before').content;
var color = window.getComputedStyle(test, ':before').color;
此外,也可以使用 CSSStyleDeclaration 實(shí)例的getPropertyValue
方法,獲取偽元素的屬性。
var result = window.getComputedStyle(test, ':before')
.getPropertyValue('content');
var color = window.getComputedStyle(test, ':before')
.getPropertyValue('color');
StyleSheet 接口
概述
StyleSheet
接口代表網(wǎng)頁(yè)的一張樣式表,包括<link>
元素加載的樣式表和<style>
元素內(nèi)嵌的樣式表。
document
對(duì)象的styleSheets
屬性,可以返回當(dāng)前頁(yè)面的所有StyleSheet
實(shí)例(即所有樣式表)。它是一個(gè)類似數(shù)組的對(duì)象。
var sheets = document.styleSheets;
var sheet = document.styleSheets[0];
sheet instanceof StyleSheet // true
如果是<style>
元素嵌入的樣式表,還有另一種獲取StyleSheet
實(shí)例的方法,就是這個(gè)節(jié)點(diǎn)元素的sheet
屬性。
// HTML 代碼為 <style id="myStyle"></style>
var myStyleSheet = document.getElementById('myStyle').sheet;
myStyleSheet instanceof StyleSheet // true
嚴(yán)格地說,StyleSheet
接口不僅包括網(wǎng)頁(yè)樣式表,還包括 XML 文檔的樣式表。所以,它有一個(gè)子類CSSStyleSheet
表示網(wǎng)頁(yè)的 CSS 樣式表。我們?cè)诰W(wǎng)頁(yè)里面拿到的樣式表實(shí)例,實(shí)際上是CSSStyleSheet
的實(shí)例。這個(gè)子接口繼承了StyleSheet
的所有屬性和方法,并且定義了幾個(gè)自己的屬性,下面把這兩個(gè)接口放在一起介紹。
實(shí)例屬性
StyleSheet
實(shí)例有以下屬性。
(1)StyleSheet.disabled
StyleSheet.disabled
返回一個(gè)布爾值,表示該樣式表是否處于禁用狀態(tài)。手動(dòng)設(shè)置disabled
屬性為true
,等同于在<link>
元素里面,將這張樣式表設(shè)為alternate stylesheet
,即該樣式表將不會(huì)生效。
注意,disabled
屬性只能在 JavaScript 腳本中設(shè)置,不能在 HTML 語(yǔ)句中設(shè)置。
(2)Stylesheet.href
Stylesheet.href
返回樣式表的網(wǎng)址。對(duì)于內(nèi)嵌樣式表,該屬性返回null
。該屬性只讀。
document.styleSheets[0].href
(3)StyleSheet.media
StyleSheet.media
屬性返回一個(gè)類似數(shù)組的對(duì)象(MediaList
實(shí)例),成員是表示適用媒介的字符串。表示當(dāng)前樣式表是用于屏幕(screen),還是用于打?。╬rint)或手持設(shè)備(handheld),或各種媒介都適用(all)。該屬性只讀,默認(rèn)值是screen
。
document.styleSheets[0].media.mediaText
// "all"
MediaList
實(shí)例的appendMedium
方法,用于增加媒介;deleteMedium
方法用于刪除媒介。
document.styleSheets[0].media.appendMedium('handheld');
document.styleSheets[0].media.deleteMedium('print');
(4)StyleSheet.title
StyleSheet.title
屬性返回樣式表的title
屬性。
(5)StyleSheet.type
StyleSheet.type
屬性返回樣式表的type
屬性,通常是text/css
。
document.styleSheets[0].type // "text/css"
(6)StyleSheet.parentStyleSheet
CSS 的@import
命令允許在樣式表中加載其他樣式表。StyleSheet.parentStyleSheet
屬性返回包含了當(dāng)前樣式表的那張樣式表。如果當(dāng)前樣式表是頂層樣式表,則該屬性返回null
。
if (stylesheet.parentStyleSheet) {
sheet = stylesheet.parentStyleSheet;
} else {
sheet = stylesheet;
}
(7)StyleSheet.ownerNode
StyleSheet.ownerNode
屬性返回StyleSheet
對(duì)象所在的 DOM 節(jié)點(diǎn),通常是<link>
或<style>
。對(duì)于那些由其他樣式表引用的樣式表,該屬性為null
。
// HTML代碼為
// <link rel="StyleSheet" href="example.css" type="text/css" />
document.styleSheets[0].ownerNode // [object HTMLLinkElement]
(8)CSSStyleSheet.cssRules
CSSStyleSheet.cssRules
屬性指向一個(gè)類似數(shù)組的對(duì)象(CSSRuleList
實(shí)例),里面每一個(gè)成員就是當(dāng)前樣式表的一條 CSS 規(guī)則。使用該規(guī)則的cssText
屬性,可以得到 CSS 規(guī)則對(duì)應(yīng)的字符串。
var sheet = document.querySelector('#styleElement').sheet;
sheet.cssRules[0].cssText
// "body { background-color: red; margin: 20px; }"
sheet.cssRules[1].cssText
// "p { line-height: 1.4em; color: blue; }"
每條 CSS 規(guī)則還有一個(gè)style
屬性,指向一個(gè)對(duì)象,用來讀寫具體的 CSS 命令。
cssStyleSheet.cssRules[0].style.color = 'red';
cssStyleSheet.cssRules[1].style.color = 'purple';
(9)CSSStyleSheet.ownerRule
有些樣式表是通過@import
規(guī)則輸入的,它的ownerRule
屬性會(huì)返回一個(gè)CSSRule
實(shí)例,代表那行@import
規(guī)則。如果當(dāng)前樣式表不是通過@import
引入的,ownerRule
屬性返回null
。
實(shí)例方法
(1)CSSStyleSheet.insertRule()
CSSStyleSheet.insertRule
方法用于在當(dāng)前樣式表的插入一個(gè)新的 CSS 規(guī)則。
var sheet = document.querySelector('#styleElement').sheet;
sheet.insertRule('#block { color: white }', 0);
sheet.insertRule('p { color: red }', 1);
該方法可以接受兩個(gè)參數(shù),第一個(gè)參數(shù)是表示 CSS 規(guī)則的字符串,這里只能有一條規(guī)則,否則會(huì)報(bào)錯(cuò)。第二個(gè)參數(shù)是該規(guī)則在樣式表的插入位置(從0開始),該參數(shù)可選,默認(rèn)為0(即默認(rèn)插在樣式表的頭部)。注意,如果插入位置大于現(xiàn)有規(guī)則的數(shù)目,會(huì)報(bào)錯(cuò)。
該方法的返回值是新插入規(guī)則的位置序號(hào)。
注意,瀏覽器對(duì)腳本在樣式表里面插入規(guī)則有很多限制。所以,這個(gè)方法最好放在try...catch
里使用。
(2)CSSStyleSheet.deleteRule()
CSSStyleSheet.deleteRule
方法用來在樣式表里面移除一條規(guī)則,它的參數(shù)是該條規(guī)則在cssRules
對(duì)象中的位置。該方法沒有返回值。
document.styleSheets[0].deleteRule(1);
實(shí)例:添加樣式表
網(wǎng)頁(yè)添加樣式表有兩種方式。一種是添加一張內(nèi)置樣式表,即在文檔中添加一個(gè)<style>
節(jié)點(diǎn)。
// 寫法一
var style = document.createElement('style');
style.setAttribute('media', 'screen');
style.innerHTML = 'body{color:red}';
document.head.appendChild(style);
// 寫法二
var style = (function () {
var style = document.createElement('style');
document.head.appendChild(style);
return style;
})();
style.sheet.insertRule('.foo{color:red;}', 0);
另一種是添加外部樣式表,即在文檔中添加一個(gè)<link>
節(jié)點(diǎn),然后將href
屬性指向外部樣式表的 URL。
var linkElm = document.createElement('link');
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute('type', 'text/css');
linkElm.setAttribute('href', 'reset-min.css');
document.head.appendChild(linkElm);
CSSRuleList 接口
CSSRuleList 接口是一個(gè)類似數(shù)組的對(duì)象,表示一組 CSS 規(guī)則,成員都是 CSSRule 實(shí)例。
獲取 CSSRuleList 實(shí)例,一般是通過StyleSheet.cssRules
屬性。
// HTML 代碼如下
// <style id="myStyle">
// h1 { color: red; }
// p { color: blue; }
// </style>
var myStyleSheet = document.getElementById('myStyle').sheet;
var crl = myStyleSheet.cssRules;
crl instanceof CSSRuleList // true
CSSRuleList 實(shí)例里面,每一條規(guī)則(CSSRule 實(shí)例)可以通過rules.item(index)
或者rules[index]
拿到。CSS 規(guī)則的條數(shù)通過rules.length
拿到。還是用上面的例子。
crl[0] instanceof CSSRule // true
crl.length // 2
注意,添加規(guī)則和刪除規(guī)則不能在 CSSRuleList 實(shí)例操作,而要在它的父元素 StyleSheet 實(shí)例上,通過StyleSheet.insertRule()
和StyleSheet.deleteRule()
操作。
CSSRule 接口
概述
一條 CSS 規(guī)則包括兩個(gè)部分:CSS 選擇器和樣式聲明。下面就是一條典型的 CSS 規(guī)則。
.myClass {
color: red;
background-color: yellow;
}
JavaScript 通過 CSSRule 接口操作 CSS 規(guī)則。一般通過 CSSRuleList 接口(StyleSheet.cssRules
)獲取 CSSRule 實(shí)例。
// HTML 代碼如下
// <style id="myStyle">
// .myClass {
// color: red;
// background-color: yellow;
// }
// </style>
var myStyleSheet = document.getElementById('myStyle').sheet;
var ruleList = myStyleSheet.cssRules;
var rule = ruleList[0];
rule instanceof CSSRule // true
CSSRule 實(shí)例的屬性
(1)CSSRule.cssText
CSSRule.cssText
屬性返回當(dāng)前規(guī)則的文本,還是使用上面的例子。
rule.cssText
// ".myClass { color: red; background-color: yellow; }"
如果規(guī)則是加載(@import
)其他樣式表,cssText
屬性返回@import 'url'
。
(2)CSSRule.parentStyleSheet
CSSRule.parentStyleSheet
屬性返回當(dāng)前規(guī)則所在的樣式表對(duì)象(StyleSheet 實(shí)例),還是使用上面的例子。
rule.parentStyleSheet === myStyleSheet // true
(3)CSSRule.parentRule
CSSRule.parentRule
屬性返回包含當(dāng)前規(guī)則的父規(guī)則,如果不存在父規(guī)則(即當(dāng)前規(guī)則是頂層規(guī)則),則返回null
。
父規(guī)則最常見的情況是,當(dāng)前規(guī)則包含在@media
規(guī)則代碼塊之中。
// HTML 代碼如下
// <style id="myStyle">
// @supports (display: flex) {
// @media screen and (min-width: 900px) {
// article {
// display: flex;
// }
// }
// }
// </style>
var myStyleSheet = document.getElementById('myStyle').sheet;
var ruleList = myStyleSheet.cssRules;
var rule0 = ruleList[0];
rule0.cssText
// "@supports (display: flex) {
// @media screen and (min-width: 900px) {
// article { display: flex; }
// }
// }"
// 由于這條規(guī)則內(nèi)嵌其他規(guī)則,
// 所以它有 cssRules 屬性,且該屬性是 CSSRuleList 實(shí)例
rule0.cssRules instanceof CSSRuleList // true
var rule1 = rule0.cssRules[0];
rule1.cssText
// "@media screen and (min-width: 900px) {
// article { display: flex; }
// }"
var rule2 = rule1.cssRules[0];
rule2.cssText
// "article { display: flex; }"
rule1.parentRule === rule0 // true
rule2.parentRule === rule1 // true
(4)CSSRule.type
CSSRule.type
屬性返回一個(gè)整數(shù)值,表示當(dāng)前規(guī)則的類型。
最常見的類型有以下幾種。
- 1:普通樣式規(guī)則(CSSStyleRule 實(shí)例)
- 3:
@import
規(guī)則 - 4:
@media
規(guī)則(CSSMediaRule 實(shí)例) - 5:
@font-face
規(guī)則
CSSStyleRule 接口
如果一條 CSS 規(guī)則是普通的樣式規(guī)則(不含特殊的 CSS 命令),那么除了 CSSRule 接口,它還部署了 CSSStyleRule 接口。
CSSStyleRule 接口有以下兩個(gè)屬性。
(1)CSSStyleRule.selectorText
CSSStyleRule.selectorText
屬性返回當(dāng)前規(guī)則的選擇器。
var stylesheet = document.styleSheets[0];
stylesheet.cssRules[0].selectorText // ".myClass"
注意,這個(gè)屬性是可寫的。
(2)CSSStyleRule.style
CSSStyleRule.style
屬性返回一個(gè)對(duì)象(CSSStyleDeclaration 實(shí)例),代表當(dāng)前規(guī)則的樣式聲明,也就是選擇器后面的大括號(hào)里面的部分。
// HTML 代碼為
// <style id="myStyle">
// p { color: red; }
// </style>
var styleSheet = document.getElementById('myStyle').sheet;
styleSheet.cssRules[0].style instanceof CSSStyleDeclaration
// true
CSSStyleDeclaration 實(shí)例的cssText
屬性,可以返回所有樣式聲明,格式為字符串。
styleSheet.cssRules[0].style.cssText
// "color: red;"
styleSheet.cssRules[0].selectorText
// "p"
CSSMediaRule 接口
如果一條 CSS 規(guī)則是@media
代碼塊,那么它除了 CSSRule 接口,還部署了 CSSMediaRule 接口。
該接口主要提供media
屬性和conditionText
屬性。前者返回代表@media
規(guī)則的一個(gè)對(duì)象(MediaList 實(shí)例),后者返回@media
規(guī)則的生效條件。
// HTML 代碼如下
// <style id="myStyle">
// @media screen and (min-width: 900px) {
// article { display: flex; }
// }
// </style>
var styleSheet = document.getElementById('myStyle').sheet;
styleSheet.cssRules[0] instanceof CSSMediaRule
// true
styleSheet.cssRules[0].media
// {
// 0: "screen and (min-width: 900px)",
// appendMedium: function,
// deleteMedium: function,
// item: function,
// length: 1,
// mediaText: "screen and (min-width: 900px)"
// }
styleSheet.cssRules[0].conditionText
// "screen and (min-width: 900px)"
window.matchMedia()
基本用法
window.matchMedia()
方法用來將 CSS 的Media Query
條件語(yǔ)句,轉(zhuǎn)換成一個(gè) MediaQueryList 實(shí)例。
var mdl = window.matchMedia('(min-width: 400px)');
mdl instanceof MediaQueryList // true
上面代碼中,變量mdl
就是 mediaQueryList 的實(shí)例。
注意,如果參數(shù)不是有效的MediaQuery
條件語(yǔ)句,window.matchMedia
不會(huì)報(bào)錯(cuò),依然返回一個(gè) MediaQueryList 實(shí)例。
window.matchMedia('bad string') instanceof MediaQueryList // true
MediaQueryList 接口的實(shí)例屬性
MediaQueryList 實(shí)例有三個(gè)屬性。
(1)MediaQueryList.media
MediaQueryList.media
屬性返回一個(gè)字符串,表示對(duì)應(yīng)的 MediaQuery 條件語(yǔ)句。
var mql = window.matchMedia('(min-width: 400px)');
mql.media // "(min-width: 400px)"
(2)MediaQueryList.matches
MediaQueryList.matches
屬性返回一個(gè)布爾值,表示當(dāng)前頁(yè)面是否符合指定的 MediaQuery 條件語(yǔ)句。
if (window.matchMedia('(min-width: 400px)').matches) {
/* 當(dāng)前視口不小于 400 像素 */
} else {
/* 當(dāng)前視口小于 400 像素 */
}
下面的例子根據(jù)mediaQuery
是否匹配當(dāng)前環(huán)境,加載相應(yīng)的 CSS 樣式表。
var result = window.matchMedia("(max-width: 700px)");
if (result.matches){
var linkElm = document.createElement('link');
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute('type', 'text/css');
linkElm.setAttribute('href', 'small.css');
document.head.appendChild(linkElm);
}
(3)MediaQueryList.onchange
如果 MediaQuery 條件語(yǔ)句的適配環(huán)境發(fā)生變化,會(huì)觸發(fā)change
事件。MediaQueryList.onchange
屬性用來指定change
事件的監(jiān)聽函數(shù)。該函數(shù)的參數(shù)是change
事件對(duì)象(MediaQueryListEvent 實(shí)例),該對(duì)象與 MediaQueryList 實(shí)例類似,也有media
和matches
屬性。
var mql = window.matchMedia('(max-width: 600px)');
mql.onchange = function(e) {
if (e.matches) {
/* 視口不超過 600 像素 */
} else {
/* 視口超過 600 像素 */
}
}
上面代碼中,change
事件發(fā)生后,存在兩種可能。一種是顯示寬度從600像素以上變?yōu)橐韵?,另一種是從600像素以下變?yōu)橐陨希栽诒O(jiān)聽函數(shù)內(nèi)部要判斷一下當(dāng)前是哪一種情況。
MediaQueryList 接口的實(shí)例方法
MediaQueryList 實(shí)例有兩個(gè)方法MediaQueryList.addListener()
和MediaQueryList.removeListener()
,用來為change
事件添加或撤銷監(jiān)聽函數(shù)。
var mql = window.matchMedia('(max-width: 600px)');
// 指定監(jiān)聽函數(shù)
mql.addListener(mqCallback);
// 撤銷監(jiān)聽函數(shù)
mql.removeListener(mqCallback);
function mqCallback(e) {
if (e.matches) {
/* 視口不超過 600 像素 */
} else {
/* 視口超過 600 像素 */
}
}
注意,MediaQueryList.removeListener()
方法不能撤銷MediaQueryList.onchange
屬性指定的監(jiān)聽函數(shù)。
更多建議: