JavaScript權威指南--腳本化CSS

 知識要點

客戶端javascript程序員對CSS感興趣的是由於樣式能夠經過腳本編程。腳本化css啓用了一系列有趣的視覺效果。例如:能夠建立動畫讓文檔從右側「滑入」。創造這些效果的javascriptcss技術在之前統稱爲動態HTML(DHTML).而如今,這個技術術語已經不流行了。javascript

爲了理解CSS腳本化,咱們必須CSS的基礎和最經常使用的樣式屬性。css

1.CSS概述

HTML的視覺顯示包含不少變量:字體,顏色、間距等。css標準列舉了這些變量,稱爲樣式屬性。html

緊跟屬性名的是冒號和值。多個屬性時用分號隔開。CSS忽略了/* */之間的註釋,可是它不支持//後面的註釋。java

兩種方式將一組定義視覺表現的CSS屬性和對於的HTML元素關聯在一塊兒。第一種是經過給每一個單獨的HTML元素設置style屬性的方式,稱爲內聯樣式。ios

儘管如此,一般將單獨的HTML元素和CSS樣式表分開,並把他們定義在一個樣式表(stylesheet)中會更有用,樣式表經過選擇器將一組樣式屬性和使用選擇器(selector)描述的一組HTML元素關聯在一塊兒。程序員

CSS樣式表的基本元素是樣式規則,它們由選擇器和包裹在一對{}中的css屬性和值所組成。每一個樣式表能夠包含任意數量的樣式規則。在<style>標籤使用或者保存爲單獨文件並經過<link>引入。web

1.1.層疊

回想下,在CSS的「C」表明了「層疊」、該術語指定了應用於文檔中任何給定元素的樣式規則是各個「來源」的「層疊」效果:chrome

  • web瀏覽器的默認樣式表
  • 文檔的樣式表
  • 每一個獨立的HTML元素的style屬性 

style屬性的樣式表覆蓋了樣式表中的樣式,而且文檔的樣式表中的樣式覆蓋了瀏覽器的默認樣式。編程

爲了顯示文檔元素,web瀏覽器「必須」組合元素的style屬性。計算結果是一組實際用於顯示元素的樣式屬性和值。這組值就是元素的「計算樣式」(computed style)。數組

1.2.CSS歷史

CSS歷史是一個相對較老的標準,CSS1在1996年12月被採納,它定義了具體的顏色,字體,外邊距,邊框和其它的旗本樣式。該標準的第二版css2在1998年被採納,定義了不少高級特性,最著名的就是元素的絕對定位。css2.1澄清和更正了css2,而且它刪除了瀏覽器供應商從未實現的功能。如今的瀏覽器基本上都徹底支持css2.1,可是低於IE8的IE還有一些遺漏問題。在css後續的工做中,針對版本3,CSS規範意見拆分紅各類各樣的專門化模塊,分別來經過標準化進程。能夠經過http://www.w3.org/Style/CSS/current-work找到css規範和工做草案。

1.3.複合屬性

某些常常在一塊兒使用的樣式屬性能夠組合起來使用一個特殊的複合屬性。例如font-family、font-size、font-weight屬性能夠用font的複合屬性一次性設置

1.4.非標準屬性

當瀏覽器廠商實現非標準CSS屬性時,他們將屬性名前加了一個廠商前綴。Firefox使用-moz-,Chrome使用-wibkit-,而IE則使用-ms-,它們甚至用這種方式來實現未來會標準化的屬性。

在不一樣的瀏覽器中不一樣名字的CSS屬性一塊兒工做,你能夠能發現一個屬性定義一個類方式比較好:

.radius10{
  border-radius:10px; /*針對現代瀏覽器*/
  -moz-border-radius:10px; /*針對firefox 3.x*/
  -webkit-border-radius:10px; /*針對safari 3.2和4*/
}

像這樣定義一個類叫「radios10」,能夠將它添加到任意須要10像素圓角的元素的類上。

1.5.CSS舉例

 

2.重要的css屬性

對於客戶端程序員來講,最重要的css特性是那些指定文檔中每一個元素的可見性、尺寸和精肯定位的屬性。其它css屬性容許指定堆疊的次序、透明度、裁剪區域、外邊距、內邊距、邊框、顏色。爲了腳本化css。理解這些樣式屬性的工做原理是很是重要的。

2.1.用css定位元素

CSS的position指定了應用到元素上的定位類型,以下是4個可能出現的屬性值:

  • static:默認屬性.指定元素按照常規的文檔內容流。靜態定位的元素不能使用top,left和相似其它的屬性定位。若是想對該文檔元素使用css定位技術,必須將position屬性值設置爲除此以外的其它3個屬性值。
  • absolute:該值指定元素是相對於它包含的元素進行定位。相對於全部其它的元素,絕對定位的元素是獨立定位的,它不是靜態定位的元素中文檔流的一部分。它的定位要麼是相對於最近定位祖先元素,要麼是相對於文檔自己。
  • fixed:該值的定位元素是相對於瀏覽器窗口進行定位的。固定定位的元素始終顯示在那裏。固定定位的元素和其它元素是獨立的。不是文檔流的一部分。除了ie6不支持外 ,其它現代的瀏覽器都支持它。
  • relative:當position屬性設置爲relative,元素會按照常規的文檔流進行佈局,它的定位相對於它文檔流中的位置進行調整。系統保留着元素正常文檔流中的空間。不會由於要填充空間將其各邊合攏。也不會將新的元素重新的位置「推開」

一旦設置了元素的position屬性爲除了static之外的值,就能夠經過元素的left,top,right,bottom屬性的一些組合指定元素的位置。

若是元素使用絕對定位,它的top和left屬性應該解釋爲它是相對於其position屬性設置爲除static值之外的祖先元素。若是絕對定位的元素沒有定位過的祖先,則使用文檔座標進行度量——就是相對於文檔左上角的偏移量。若是想相對於一個屬於常規文檔流中的容器絕對定位一個元素,則將容器的position指定爲relative,top和left指定爲0px。這就讓容器變成了動態定位,但它仍留在文檔流中原來的位置。

指定元素的寬度能夠用width,另外一種方法是同時指定left和right屬性,高度也同樣。若是同時指定left、right和width,那麼width屬性將覆蓋right屬性,height屬性優先於bottom屬性。

<head>
    <meta charset="utf-8">
</head>
<style type="text/css">
    .out{position: relative;left: 0;right: 0;width: 500px;height: 500px;background: #ccc;}
    .in{position: absolute;left: 100px;right: 100px;top: 100px;bottom: 100px;width: 200px;background: #aaa;}
</style>
<body>
    <div class="out">
        <div class="in">絕對定位</div>
    </div>
</body>

單位:px、in、cm、pt、em等等。

1.第三個維度

上面講的是在二維座標中指定X和Y座標,z-index定義第三個維度容許指定元素的堆疊次序。默認爲0,能夠是正負整數若是重疊元素的z-index值同樣,則按照在文檔中出現的順序繪製,即最後一個重疊的元素顯示在最上面

注意:z-index只對兄弟元素應用堆疊效果。

非定位元素(例如,默認使用position:static定位)老是以防止重疊的方式進行佈局,由於z-index屬性不會應用到他們上面。儘管如此,它們默認的z-index值爲0,這意味着z-index爲正值的定位元素顯示在常規文檔流的上面,而z-index爲負直的定位元素顯示在常規文檔流的下面。

2.CSS定位示例:文本陰影

CSS3有text-shadow屬性能夠產生文本陰影效果,用CSS定位也能夠實現,只要重複輸出這段文本並從新定義一下樣式:

<body>
    <!-- text-shadow屬性 -->
    <span style="text-shadow: 3px 3px 1px #888">Shadowed</span>

    <!-- 利用定位 -->
    <span style="position: relative;">
        Shadowed
        <span style="position: absolute;top: 3px;left: 3px;z-index: -1;color: #888">
            Shadowed
        </span>
    </span>
</body>

2.2.邊框,外邊距,內邊距

邊框樣式border,指定邊框的樣式、樣式和厚度,也能夠單獨指定。

在CSS3中能夠用border-radius指定圓角,也能夠設置單獨的圓角。

margin和padding屬性。

2.3.CSS盒模型和定位細節

以上描述的margin,border和padding等樣式屬性在腳本化時極可能不常用。由於他們是CSS盒模型(box model)的一部分

left和top屬性指定了從容器邊框內側到定位元素邊框外側的距離。這些屬性不是從容器內容區域的左上角開始度量的,而是從容器內邊距的左上角開始的。一樣,right和bottom屬性是從容器內邊距的右下角開始度量的。

有一個例子說明這點。假設已建立一個在內容區域四周有10px padding和5px border的動態定位的容器元素。假設一個定位的子元素將left設爲0px,則子元素會靠在容器左邊框的右邊,覆蓋了容器的內邊距。因此若是要這樣作的話須要設置left爲10px。

邊框盒模型和box-sizing屬性

標準CSS盒模型規定width和height樣式屬性給定內容區域尺寸,並且不包含內邊距和邊框。能夠稱此爲「內容盒模型」。在老版的IE和新版的CSS都有一些例外 ,在IE6以前和當IE6-8在怪異模式下,顯示一個頁面(頁面缺乏<!DOCTYPE>或有一個不嚴格的doctype時),width和height屬性確是包含內邊距和邊框寬度的。

可是這樣也有用,因此CSS3引進了box-sizing屬性,默認值是content-box,它指定執行頁面的標準盒模型,若是替換爲box-sizing:border-box,瀏覽器將會爲那個元素應用IE的盒模型,即:width和height包含邊框和內邊框。當想以百分比形式爲元素設置整體尺寸,又想以像素指定邊框和內邊距時,邊框盒模型特別有用。

<div style="box-sizing:border-box;width: 50%;padding: 10px;border: 2px solid red;"></div>

box-sizing屬性在當今的瀏覽器中都支持,可是還沒不帶前綴通用地實現。能夠在chrome和safari中使用-webikit-box-sizing,在firefox中,使用-moz-box-sizing。在IE後等其餘瀏覽器更高的版本中,可使用不帶前綴的box-sizing。

在CSS3中一個可選方案是使用盒子尺寸的計算值:

<div style="width: calc(50%-12px);padding:10px;border: solid red 2px;"></div>

在IE9中支持使用calc()計算css的值。在Firefox4中爲-moz-calc()。

2.4.元素的顯示和可見性

兩個CSS的屬性影響了文檔元素的可見性:visibility和displayvisibility屬性很簡單。當其值設置爲hidden時,該元素不顯示。當其值設置爲visible時,該元素顯示。display屬性更加通用。它用來接收它的容器指定元素顯示的類型。它指定元素是塊級元素、內聯元素、列表項等。但當display設置爲none,受影響的元素將不顯示,甚至根本沒有佈局。

visibility和display屬性之間的差異能夠從他們對使用靜態或至關定位元素的影響中看到。對於一個常規佈局流中的元素,設置visibility屬性爲hidden使得元素不可見,但在文檔佈局中保留了它的空間。相似的元素能夠重複隱藏和顯示而不改變文檔佈局。可是,當display屬性設置爲none,在文檔佈局中不給它分配空間。使得各邊元素會靠攏,就當不存在。例如在建立和展開摺疊的效果時display屬性就頗有用。

visibility和display屬性對絕對和固定定位的元素影響是等價的。由於這些元素都不是文檔佈局的一部分。然而,在隱藏和顯示定位元素時通常首選visibility屬性。

注意,使用visibility和display屬性是的元素不可見沒有什麼意義。除非使用javascript動態設置這些屬性讓元素在某一刻可見!

2.5.顏色、透明度和半透明度

文本元素、背景顏色、邊框顏色。

在CSS中更通常指定顏色的語法是使用十六進制數分別指定組成顏色的紅、綠和藍色份量,每一個份量可使用一位後兩位數字

CSS3也指定RGBA彩色空間。CSS3也定義了對HSL(色相-飽和度-值)和HSLA顏色規範的支持。他們在FIrefox、Safari、Chrome中都支持,除了IE。

除了background-color屬性,也能夠爲元素指定背景圖像:background-image屬性以及一些高級細節設置。使用複合屬性background直接搞定。

若是沒有爲元素指定背景顏色或圖象,它的背景一般透明,理解這點很是重要,例如一個空的<div>絕對定位。儘管如此,默認狀況下不是全部元素都是透明的,例如,具備透明背景的表單元素看起來不透明,而且元素<button>有默認的背景顏色用background-color屬性能夠覆蓋默認顏色,若是強烈要求能夠將其顯式設置爲"transpanrent"。

CSS3的opacity屬性處理元素的透明,該屬性值爲0-1之間的數字、opacity屬性在當今全部的瀏覽器都支持。除了IE,IE提供可選方式:特有的filter屬性。

opacity:.75
filter:alpha(opacity=75);

2.6.部分可見:overflow和clip

visibility屬性可讓文檔元素徹底隱藏,而overflow和clip屬性容許只顯示元素的一部分。overflow屬性指定內容超出元素的大小(例如:用width和 height樣式屬性指定)時如何顯示。該屬性的值和含義以下所示:

  • visible :默認值。若是須要,內容能夠溢出並繪製在元素邊框的外面
  • hidden:裁剪掉和隱藏溢出的內容。
  • scroll:元素一直顯示水平和垂直滾動條。
  • auto:滾動條只在內容超出元素的尺寸時顯示,而非一直顯示。

clip屬性確切地指定了應該顯示元素的哪一個部分,無論是否溢出在建立元素漸進顯示的腳本效果時特別有用

clip屬性的值指定了元素的裁剪區域,在css2中,裁剪區域是矩形的,不過clip屬性的語法預留了開放的可能性,該標準在未來的版本可能將支持更多形狀的裁剪。它的語法是:

/*相對於元素邊框的左上角*/
rect(top right bottom left)

例如只顯示元素的100X100的部分:

style="clip:rect(0px 100px 100px 0);"

注意:圓括號4個值時長度,因此必須包含明確單位。不容許使用百分比,能夠指定負值,也能夠爲任何4個值使用auto關鍵字來指定裁剪區域的邊緣就是元素邊框的對應邊緣。例如只顯示元素最左的100像素:

style = "clip:rect(auto 100px auto auto);"

值之間沒有逗號。將clip設置爲auto來停用裁剪功能。

2.7.示例:重疊半透明窗口

 

3.腳本化內聯樣式

腳本化css最直接了當的方法就是更改單獨的文檔元素的style屬性,相似大多數HTML屬性,style也是元素對象的屬性,它能夠在javascript操做,可是style屬性不一樣尋常:它的值不是字符串,而是一個CSSStyleDeclaration對象。該style對象的javascript屬性表明了HTML代碼中經過style指定的css屬性。例如讓元素e的文本變大號、加粗和藍色,可使用以下代碼設置font-size,font-weight和color樣式屬性對應的javascript屬性。

e.style.fontSize = "24px";
e.style.fontWeight = "bold";
e.style.color = "#007F9F";

名字約定:JavaScript中的CSS屬性

有連字符的屬性,在JavaScript是減號,不能用。所以,CSSStyleDeclaration對象中的屬性名和實際的CSS屬性名有所區別。例如連字符改成首字母大寫:CSS屬性border-left-width的值在JavaScript中爲borderLeftWidth。另外,當一個CSS屬性(如float)在JavaScript中對應的名字是保留字時,在以前加"css"前綴來建立合法的CSSStyleDeclaration名字。如float爲cssFloat。

使用CSSStyleDeclaration對象的style屬性時,記住全部值都應該是字符串,全部的定位都有有單位。

e.style.left = (x0 + left_margin + left_border + left_padding) + "px";

回想一下,一些css屬性(如margin)是margin-top/margin-right/margin-bottom/margin-left)的複合屬性。CSSStyleDeclaration對象也有與之對應的複合屬性,例如。也能像這樣設置magin屬性:

e.style.margin = topMargin + "px" + rightMargin + "px" + bootomMargin + "px" + leftMargin + "px";

獨立設置4個margin屬性值更加便捷:

e.style.marginTop = topMargin + "px";
e.style.marginRight = rightMargin + "px";
e.style.marginBottom = bottomMargin + "px";
e.style.marginLeft = leftMargin + "px";

HTML元素的style屬性是它的內聯樣式,它覆蓋在樣式表中的任何樣式說明。內聯樣式通常在設置樣式值時很是有用,就像上面的例子所說的同樣。CSSStyleDeclaration對象的屬性能夠理解爲表明內聯樣式,可是它只返回有意義的值:javascript代碼已經設置過的值或者HTML元素顯式設置了想要的內聯樣式的值。例如,文檔可能包含一個樣式表以設置全部段落的左邊距爲30px,可是擋在讀取段落元素的marginLeft屬性時會獲得一個空字符串,除非該段落有一個style屬性覆蓋了樣式表中的設置。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <style type="text/css">
        #mar0,#mar1{
            width: 100px;height: 100px;border: 2px solid #ccc;margin-left: 10px;
        }
    </style>
</head>
<body>
    <div id="mar0">margin</div><br>
    <div id="mar1" style="margin-left: 20px">margin</div>
    <script type="text/javascript">      
        window.onload = function(){
            var ma0 = document.getElementById("mar0");
            var ma1 = document.getElementById("mar1");            
            console.log(ma0.style.marginLeft);
            console.log(ma1.style.marginLeft);
        }
    </script>
</body>

讀取元素的內聯樣式特別困難,對style屬性來講必須包含單位,對複合屬性來講,在真正使用這些值的時候,代碼不得不包含非同尋常的css解析能力。總之,元素的內聯樣式只有在設置樣式的時候有用,但若是須要查詢元素的樣式,就要使用計算樣式,這將在本章4節討論。

有時,發現單個字符串值來設置或查詢元素的內聯樣式反而比做爲CSSStyleDeclaration對象更加簡單。爲此,可使用元素的getAttribute()和setAttribute()方法或CSSStyleDeclaration對象的cssText屬性來實現:

 //二者均可以設置e的樣式屬性爲字符串s
e.setAttribute("style", s);
s = e.style.cssText;
 //二者均可以查詢元素的內聯樣式
s = e.getAttribute("style");
s = e.style.cssText;

CSS動畫

腳本化的css最多見的用途之一就是產生視覺動畫,使用setTimeout()或setTinterval()(12章1節),重複調用函數來修改元素的內聯樣式達到目的。下面的例子用shake()和fadeOut()來舉例說明。shake()將元素從一邊快速移動到另外一邊震動。例如當輸入無效數據時,會吸引用戶注意力。fadeOut()經過制定時間(默認500毫秒)下降元素不透明度,使得元素淡出和消失。

//將e轉化爲相對定位的元素,使之左右「震動」
//第一個參數能夠是圓度對象或者元素的id
//若是第二個參數是函數,以e爲參數,將在動畫結束時調用;第三個參數指定e震動的距離,例如5px
//第四個參數指定震動多久,默認500毫秒
function shake(e, oncomplete, distance, time) {
    //句柄參數
    if (typeof e === "string") e = document.getElementById(e);
    if (!time) time = 500;
    if (!distance) distance = 5;
    
    var originalStyle = e.style.cssText; //保存e的原始style
    e.style.position = "relative"; //使e相對定位
    var start = (new Date()).getTime(); //注意,動畫的開始時間
    animate(); //動畫開始
    //函數檢查消耗時間,並更新e的位置
    //若是動畫完成,它將e還原爲原始狀態
    //不然,更新e的位置,安排它自身重新運行
    function animate() {
        var now = (new Date()).getTime(); //獲得當前時間
        var elapsed = now - start; //從開始以來消耗了多長時間
        //是總時間的幾分之幾
        var fraction = elapsed / time;
        if (fraction < 1) { //若是動畫未完成
            //做爲動畫完成的比例函數,計算e的x位置
            //使用正弦函數將完成的比例乘以4pi
            //因此,它來回往復兩次
            var x = distance * Math.sin(fraction * 4 * Math.PI);
            e.style.left = x + "px";
            //在25毫秒以後或在總時間最後嘗試再次運行函數
            //目的是爲了產生每秒40幀的動畫
            setTimeout(animate, Math.min(25, time - elapsed));
        } else { //不然動畫完成
            e.style.cssText = originalStyle //恢復原始樣式
            if (oncomplete) oncomplete(e); //調用完成後回調函數
        }
    }
}
//以毫秒級時間將e從徹底不透明到透明
//在調用函數時假設e是徹底不透明的
//oncomplate是一個可選函數,以e爲參數,在動畫結束調用
//若是不指定time.默認500
//本函數ie中不能正常構造
//除了opacity,ie使用非標準的filter屬性
function fadeOut(e,oncomplete,time){
    if(typeof e === "string") e = document.getElementById(e);
    if(!time) time =500;
    
    //使用Math.sqrt做爲一個簡單的緩動函數來建立動畫
    //精巧的非線性:一開始淡的比較快,而後慢一些
    var ease = Math.sqrt;
    
    var start = (new Date()).getTime(); //注意動畫開始的實際
    animate();//動畫開始
    
    function animate(){
        var elapsed = (new Date()).getTime() - start ;//消耗時間
         //總時間的幾分之幾
        var fraction = elapsed/time;
        if(fraction < 1){//動畫未完成
            var opacity = 1 - ease(fraction);//計算元素不透明
            e.style.opacity =String(opacity); //設置在e上
            setTimeout(animate,Math.min(25,time-elapsed));
        }
        else{
            e.style.opacity = "0";
            if(oncomplete) oncomplete(e); //調用完成後回調函數
        }
    }
}

shake()和fadeOut()都能接受可選的回調函數做爲第二個參數,若是指定了,當動畫結束時函數將被調用。該動畫元素將做爲回調函數的參數傳遞進去。下面的代碼建立了一個按鈕,當單擊時,左右震動並淡出。

<button onclick="shake(this,fadeOut)">點擊我</button>

注意,shake()和fadeOut()示例函數之間很是類似,都能做爲相似css屬性動畫的模板。客戶端類庫,如jQury一般支持預約義的視覺效果,所以,除非想建立特別複雜的視覺效果,實際上不用寫相似shake()動畫函數。scriptaculous是早期一個值得關注的類庫,它是爲prototype框架設計的。http://scripty2.com/

爲了不使用任何腳本,CSS3的過渡模塊定義了在樣式表中指定動畫效果的方式。例如,爲了替代定義相似fadeOut()這樣的函數,可使用以下的css:

.fadeable{transition:opacity .5s ease-in}

4.查詢計算出的樣式

元素的style屬性表明了元素的內聯樣式,它覆蓋全部的樣式表,它是設置CSS屬性值來改變元素的視覺表現最好的地方。可是,它在查詢元素實際應用的樣式時用處不大。爲此,你想要使用計算樣式。元素的計算樣式是一組屬性值,它由瀏覽器經過把內聯樣式結合全部連接樣式表中全部可應用的樣式規則後導出(或計算)獲得的:它就是一組在顯示元素時實際使用的屬性值相似內聯樣式,計算樣式也是一個CSSStyleDeclaration對象來表示的,區別是,計算樣式是隻讀的。雖然不能設置這些樣式,但爲元素計算出的CSSStyleDeclaration對象確切地決定了瀏覽器在渲染元素時使用的樣式屬性值。

用瀏覽器窗口對象的getComputedStyle()方法來獲取一個元素的計算樣式。接收兩個參數:第一個是要取得其計算樣式的元素,第二個也是必須的,一般是null或空字符串,也能夠是命名CSS僞對象字符串,如「:before」、「:after」、「:first-line」、「:first-letter」。

var title = document.getElementById("section1title");
var titlestyles = window.getComputedStyle(element,null);

getComputedStyle()方法返回一個CSSStyleDeclaration對象,其中包含當前元素的全部計算的樣式。

表示計算樣式的CSSStyleDeclaration對象和表示內聯樣式的對象之間有一些重要的區別:

  • 計算樣式的屬性是隻讀的;
  • 計算樣式的值是絕對值,相似百分比和點之類相對的單位將所有轉換絕對值。全部指定尺寸的屬性都有一個以像素爲度量單位的值。該值將是一個冠以"px"後綴的字符串,使用時仍然須要解析它,可是不用擔憂單位的解析或轉換。其值是顏色的屬性將以「rgb(#,#,#)」或「rgba(#,#,#,#)」的格式返回;
  • 不計算複合屬性,它們只基於最基礎的屬性,如不要查詢margin,應該使用marginTop等;
  • 計算樣式的cssText屬性未定義;

計算樣式和內聯樣式能夠同時使用。下面例子定義了scale()和scaleColor()函數。一個用來查詢和解析指定元素的計算文本尺寸,另外一個查詢和解析元素的計算背景顏色。兩個函數都將結果值按比例縮放並做爲元素的內聯樣式設置縮放值。

。。。。。。

計算樣式也具備欺騙性,查詢它們獲得的信息也不老是如人所願好比font-family屬性:爲了適應跨平臺可移植性,可能會接受字體列表,當查詢一個計算樣式的fontFamily屬性時,可能返回一系列的字體如"arial,helvetica,san-serif",而沒法告訴你實際使用哪一種字體。相似的,若是沒有使用絕對定位,試圖經過計算樣式的top和left屬性會返回"auto",這個是合法的,但不是想要的。

在IE中,每一個HTML元素有本身的currentStyle屬性,它的值是CSSStyleDeclaration對象。IE的currentStyle組合了內聯樣式和樣式表,但他不是真正的計算樣式,由於相對值都沒有轉換爲字符串(會帶有"%"、"em"或"red"等等)。

查詢元素的計算樣式不是斷定元素尺寸和位置的完美方法,另外一種更簡單的在15.8.2節。

5.腳本化CSS類

經過內聯style屬性腳本化CSS樣式的一個可選方案是腳本化HTML的clss屬性值。改變了元素的class就改變了應用於元素的一組樣式表選擇器,它能在同一時刻改變多個CSS屬性。例如,假設想讓用戶對文檔中的單獨段落(或其它元素)引發注意。首先,爲任意元素定義一個名爲"attention"的類:

.attention{/*吸引用戶注意*/
    background-color:yellow;
    font-weight: bold;
    border: solid black 2px;
}

標識符class在javascript中是保留字,因此HTML屬性class在javascript代碼中應該可用於使用calssName的javascript代碼。以下的代碼設置和清除元素的className屬性來爲元素添加和移除"attention"類:

function grabAttention(e){e.className = "attention";}
function releaseAttention(e) {e.className = "";}

HTML元素能夠有多個CSS類名,class屬性保存了一個用空格隔開的類名列表。上面的函數假設className屬性只指定零個或一個類名,若是有多個類名就沒法工做了。若是元素已經有一個類,調用上面grabAttention()函數將覆蓋已經存在的類。

HTML5爲了解決這個問題,爲每一個元素定義了classList屬性該屬性的值是DOMTokenList對象:一個只讀的類數組對象(7.11節),它包含元素的單獨類名。可是,和數組元素相比,DOMTokenList定義的方法更加劇要。add()和remove()從元素的class屬性中添加和清除一個類名。toggle()表示若是不存在的類名就添加一個;不然,刪除它。最後,contains()方法檢測class屬性中是否包含一個指定的類名。

相似其餘DOM集合類型,DOMTokenList對象「實時的」表明了元素類名集合。而並不是是在查詢classList屬性時類名的一個靜態快照。若是從元素的classList屬性中得到了一個DOMTokenList對象,而後元素的className屬性改變了,這些變化在標識列表中及時可見。一樣,改變標識列表,在ClassName屬性中及時可見。

不是全部的瀏覽器都支持classList屬性。可是這個重要的功能容易近似實現。以下代碼或使用相似的代碼,把class屬性當作一個類名的集合。使得許多腳本化的css類工做更加簡單。

。。。。。。

6.腳本化樣式表

到目前爲止,咱們已經看到如何設置和查詢CSS樣式和單個元素的類名。腳本化樣式表固然是也是可能的。雖然不常常這麼作,但偶爾卻很是有用。本節概述該技術。

在腳本化樣式表時,將會碰到兩類須要使用的對象。第一類是元素對象,由<style>和<link>元素表示,兩種元素包含或引用樣式表。這些是常規的文檔元素,若是他們有id屬性值,可使用document.getElementById()函數來選擇它們。第二類是CSSStyleSheet對象,它表示樣式表自己。document.styleSheets屬性是一個只讀的類數組對象,它包含CSSStyleSheet對象,表示與文檔關聯在一塊兒的樣式表。若是爲定義或引用了樣式表的<style>或<link>元素設置title屬性值,該title做爲對應CSSStyleSheet對象的title屬性就能夠。

6.1.開啓和關閉樣式表

最簡單的校本化樣式表的技術特是最便捷和健壯的。<style>、<link>元素和CSSStyleSheet對象都定義了一個在javascript中能夠設置和查詢的disabled屬性。顧名思義,若是disabled屬性爲true,樣式表就被瀏覽器關閉並忽略

如下disableStyleSheet()函數就說明了這一點。若是傳遞一個數字 。函數將其當作document.styleSheet數組中的一個索引,若是傳遞一個字符串。函數就將其當作CSS選擇器並傳遞給document.querySeleCtorAll()(15.2.5節),而後設置全部返回元素的disabled屬性:

function disableStyleSheeet(ss) {
    if (typeof ss === "number")
        document.styleSheets[ss].disabled = true;
    else {
        var sheet = document.querySelectorAll(ss);
        for (var i = 0; i < sheet.length; i++)
            sheet[i].disabled = true;
    }
}

6.2.查詢、插入與刪除樣式表規則

除了樣式表的開啓和關閉之外,CSSStyleSheet對象也定義了用來查詢、插入和刪除樣式表的規則API。IE8及更早版本實現的API和其它瀏覽器實現的標準API之間有一些輕微的區別。

直接操做樣式表一般沒什麼意義。典型地,相對編輯樣式表或增長新規則而言,讓樣式表保存靜態並對元素className屬性編程更好。另外一方面,若是容許用戶徹底控制頁面上的樣式,可能就須要動態操做樣式表。

document.styleSheets[]數組的元素是CSSStyleSheet對象。CSSStyleSheet對象有一個cssRules[]數組,它包含全部樣式表規則:

var firstRule = document.styleSheets[0].cssRules[0];

IE使用不一樣的屬性名rules代替cssRules

cssRules[]或rules[]數組元素爲CSSRule對象。在標準的API中,CSSRule對象表明全部的CSS規則,包含如@import和@page等指令。可是在IE中,rules[]數組只包含樣式表中實際存在的樣式規則。

CSSRule對象有兩個屬性能夠很便捷的使用。(在標準API中,非樣式規則沒有定義這些屬性,當遍歷樣式表時但願跳過去它。)selectText是規則的CSS選擇器,它引用一個描述與選擇器相關聯的樣式的可寫CSSStyleDeclaration對象。回想一個,CSSStyleDeclaration是用來表示內聯和計算樣式的相同類型。能夠利用它來查詢規則的樣式值或設置新樣式。一般,當遍歷樣式表時。你對規則的文本比它解析後的表示形式更感興趣。此時,使用CSSStyleDeclaration對象的cssText屬性來得到規則的文本表示形式。

除了查詢和修改樣式表中已存在的規則之外,也能向樣式表添加和從中刪除規則。標準的API接口定義了insertRule()和deleteRule()方法來添加和刪除規則

document.styleSheets[0].insertRule("H1 {text-weight:bold}",0);

IE不支持insertRule()和deleteRule(),但定義了大體等效的函數addRule()和removeRule()。(除了名字之外)僅有的不一樣是addRule()但願選擇器文本和樣式文本做爲兩個參數。

如下代碼遍歷樣式表樣式表的規則,舉例說明了用API對樣式表進行一些可疑的修改:

。。。。。。

6.3.建立新的樣式表

最後,建立整個新樣式表並將其添加到文檔是中可能的。在大多數瀏覽器中,能夠用標準的DOM技術:只要建立一個新的<style>元素,將其插入到文檔的頭部,而後用其innerHTML屬性來設置樣式表內容。可是在IE8以及更早的版本中,CSSStyleSheet對象經過非標準方法document.createStyleSheet()來建立,其樣式文本用cssText屬性值來指定。請看下面的例子。

。。。。。。

相關文章
相關標籤/搜索