1. 程式人生 > >JavaScript高階程式設計之DOM2和DOM3之樣式之操作樣式表第12.2.2講

JavaScript高階程式設計之DOM2和DOM3之樣式之操作樣式表第12.2.2講

CSSStyleSheet 型別表示的是樣式表,包括通過<link>元素包含的樣式表和在<style>元素中定義
的樣式表。有讀者可能記得,這兩個元素本身分別是由HTMLLinkElement 和HTMLStyleElement 型別
表示的。但是,CSSStyleSheet 型別相對更加通用一些,它只表示樣式表,而不管這些樣式表在HTML
中是如何定義的。此外,上述兩個針對元素的型別允許修改HTML 特性,但CSSStyleSheet 物件則是一

套只讀的介面(有一個屬性例外)。使用下面的程式碼可以確定瀏覽器是否支援DOM2 級樣式表。

var supportsDOM2StyleSheets =
document.implementation.hasFeature("StyleSheets", "2.0");
CSSStyleSheet 繼承自StyleSheet,後者可以作為一個基礎介面來定義非CSS 樣式表。從
StyleSheet 介面繼承而來的屬性如下。
disabled:表示樣式表是否被禁用的布林值。這個屬性是可讀/寫的,將這個值設定為true 可
以禁用樣式表。
href:如果樣式表是通過<link>包含的,則是樣式表的URL;否則,是null。
media:當前樣式表支援的所有媒體型別的集合。與所有DOM 集合一樣,這個集合也有一個
length 屬性和一個item()方法。也可以使用方括號語法取得集合中特定的項。如果集合是空
列表,表示樣式表適用於所有媒體。在IE 中,media 是一個反映<link>和<style>元素media
特性值的字串。
ownerNode:指向擁有當前樣式表的節點的指標,樣式表可能是在HTML 中通過<link>或
<style/>引入的(在XML 中可能是通過處理指令引入的)。如果當前樣式表是其他樣式表通過
@import 匯入的,則這個屬性值為null。IE 不支援這個屬性。
parentStyleSheet:在當前樣式表是通過@import 匯入的情況下,這個屬性是一個指向匯入
它的樣式表的指標。
title:ownerNode 中title 屬性的值。
type:表示樣式表型別的字串。對CSS 樣式表而言,這個字串是"type/css"。
除了disabled 屬性之外,其他屬性都是隻讀的。在支援以上所有這些屬性的基礎上,
CSSStyleSheet 型別還支援下列屬性和方法:
cssRules:樣式表中包含的樣式規則的集合。IE 不支援這個屬性,但有一個類似的rules 屬性。
ownerRule:如果樣式表是通過@import 匯入的,這個屬性就是一個指標,指向表示匯入的規
則;否則,值為null。IE 不支援這個屬性。
deleteRule(index):刪除cssRules 集合中指定位置的規則。IE 不支援這個方法,但支援
一個類似的removeRule()方法。
insertRule(rule,index):向cssRules 集合中指定的位置插入rule 字串。IE 不支援這
個方法,但支援一個類似的addRule()方法。
應用於文件的所有樣式表是通過document.styleSheets 集合來表示的。通過這個集合的length
屬性可以獲知文件中樣式表的數量,而通過方括號語法或item()方法可以訪問每一個樣式表。來看一個
例子。
var sheet = null;
for (var i=0, len=document.styleSheets.length; i < len; i++){
sheet = document.styleSheets[i];
alert(sheet.href);
}
以上程式碼可以輸出文件中使用的每一個樣式表的href 屬性(<style>元素包含的樣式表沒有
href 屬性)。
不同瀏覽器的document.styleSheets 返回的樣式表也不同。所有瀏覽器都會包含<style>元素
和rel 特性被設定為"stylesheet"的<link>元素引入的樣式表。IE 和Opera 也包含rel 特性被設定
為"alternate stylesheet"的<link>元素引入的樣式表。
也可以直接通過<link>或<style>元素取得CSSStyleSheet 物件。DOM 規定了一個包含
CSSStyleSheet 物件的屬性,名叫sheet;除了IE,其他瀏覽器都支援這個屬性。IE 支援的是
styleSheet 屬性。要想在不同瀏覽器中都能取得樣式表物件,可以使用下列程式碼。
function getStyleSheet(element){
return element.sheet || element.styleSheet;
}
//取得第一個<link/>元素引入的樣式表
var link = document.getElementsByTagName("link")[0];
var sheet = getStylesheet(link);
這裡的getStyleSheet()返回的樣式表物件與document.styleSheets 集合中的樣式表物件相同。
1. CSS
規則
CSSRule 物件表示樣式表中的每一條規則。實際上,CSSRule 是一個供其他多種型別繼承的基類
型,其中最常見的就是CSSStyleRule 型別,表示樣式資訊(其他規則還有@import、@font-face、
@page 和@charset,但這些規則很少有必要通過指令碼來訪問)。CSSStyleRule 物件包含下列屬性。
cssText:返回整條規則對應的文字。由於瀏覽器對樣式表的內部處理方式不同,返回的文字
可能會與樣式表中實際的文字不一樣;Safari 始終都會將文字轉換成全部小寫。IE 不支援這個
屬性。
parentRule:如果當前規則是匯入的規則,這個屬性引用的就是匯入規則;否則,這個值為
null。IE 不支援這個屬性。
parentStyleSheet:當前規則所屬的樣式表。IE 不支援這個屬性。
selectorText:返回當前規則的選擇符文字。由於瀏覽器對樣式表的內部處理方式不同,返回
的文字可能會與樣式表中實際的文字不一樣(例如,Safari 3 之前的版本始終會將文字轉換成全
部小寫)。在Firefox、Safari、Chrome 和IE 中這個屬性是隻讀的。Opera 允許修改selectorText。
style:一個CSSStyleDeclaration 物件,可以通過它設定和取得規則中特定的樣式值。
type:表示規則型別的常量值。對於樣式規則,這個值是1。IE 不支援這個屬性。
其中三個最常用的屬性是cssText、selectorText 和style。cssText 屬性與style.cssText
屬性類似,但並不相同。前者包含選擇符文字和圍繞樣式資訊的花括號,後者只包含樣式資訊(類似於
元素的style.cssText)。此外,cssText 是隻讀的,而style.cssText 也可以被重寫。

大多數情況下,僅使用style 屬性就可以滿足所有操作樣式規則的需求了。這個物件就像每個元
素上的style 屬性一樣,可以通過它讀取和修改規則中的樣式資訊。以下面的CSS 規則為例。

div.box {
background-color: blue;
width: 100px;
height: 200px;
}
假設這條規則位於頁面中的第一個樣式表中,而且這個樣式表中只有這一條樣式規則,那麼通過下
列程式碼可以取得這條規則的各種資訊。
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules; //取得規則列表
var rule = rules[0]; //取得第一條規則
alert(rule.selectorText); //"div.box"
alert(rule.style.cssText); //完整的CSS 程式碼
alert(rule.style.backgroundColor); //"blue"
alert(rule.style.width); //"100px"
alert(rule.style.height); //"200px"
使用這種方式,可以像確定元素的行內樣式資訊一樣,確定與規則相關的樣式資訊。與使用元素的
方式一樣,在這種方式下也可以修改樣式資訊,如下面的例子所示。
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules; //取得規則列表
var rule = rules[0]; //取得第一條規則
rule.style.backgroundColor = "red"
必須要注意的是,以這種方式修改規則會影響頁面中適用於該規則的所有元素。換句話說,如果有
兩個帶有box 類的<div>元素,那麼這兩個元素都會應用修改後的樣式。
2.
建立規則
DOM 規定,要向現有樣式表中新增新規則,需要使用insertRule()方法。這個方法接受兩個參
數:規則文字和表示在哪裡插入規則的索引。下面是一個例子。
sheet.insertRule("body { background-color: silver }", 0); //DOM 方法
這個例子插入的規則會改變元素的背景顏色。插入的規則將成為樣式表中的第一條規則(插入到了
位置0)——規則的次序在確定層疊之後應用到文件的規則時至關重要。Firefox、Safari、Opera 和Chrome
都支援insertRule()方法。
IE8 及更早版本支援一個類似的方法,名叫addRule(),也接收兩必選引數:選擇符文字和CSS
樣式資訊;一個可選引數:插入規則的位置。在IE 中插入與前面例子相同的規則,可使用如下程式碼。

sheet.addRule("body", "background-color: silver", 0); //僅對IE 有效
有關這個方法的規定中說,最多可以使用addRule()新增4 095 條樣式規則。超出這個上限的呼叫
將會導致錯誤。

要以跨瀏覽器的方式向樣式表中插入規則,可以使用下面的函式。這個函式接受4 個引數:要向其
中新增規則的樣式表以及與addRule()相同的3 個引數,如下所示。

function insertRule(sheet, selectorText, cssText, position){
if (sheet.insertRule){
sheet.insertRule(selectorText + "{" + cssText + "}", position);
} else if (sheet.addRule){
sheet.addRule(selectorText, cssText, position);
}
}
下面是呼叫這個函式的示例程式碼。
insertRule(document.styleSheets[0], "body", "background-color: silver", 0);
雖然可以像這樣來新增規則,但隨著要新增規則的增多,這種方法就會變得非常繁瑣。因此,如果
要新增的規則非常多,我們建議還是採用第10 章介紹過的動態載入樣式表的技術。
3.
刪除規則
從樣式表中刪除規則的方法是deleteRule(),這個方法接受一個引數:要刪除的規則的位置。例
如,要刪除樣式表中的第一條規則,可以使用以下程式碼。

sheet.deleteRule(0); //DOM 方法
IE 支援的類似方法叫removeRule(),使用方法相同,如下所示:
sheet.removeRule(0); //僅對IE 有效
下面是一個能夠跨瀏覽器刪除規則的函式。第一個引數是要操作的樣式表,第二個引數是要刪除的
規則的索引。
function deleteRule(sheet, index){
if (sheet.deleteRule){
sheet.deleteRule(index);
} else if (sheet.removeRule){
sheet.removeRule(index);
}
}
呼叫這個函式的方式如下。
呼叫這個函式的方式如下。
與新增規則相似,刪除規則也不是實際Web 開發中常見的做法。考慮到刪除規則可能會影響CSS
層疊的效果,因此請大家慎重使用。