ppk談JavaScript style屬性

來源:互聯網
上載者:User

事實上,7個範例指令碼都用到了某種形式的CSS修改。比如,“表單驗證”改變出錯的表單域的樣式,“XMLHTTP速度測試計”使用動畫(其實也就是在很短的時間內多次改變某個樣式)來讓使用者注意到速度的資料(而且,老實講這算是有些花哨的效果)。“下拉式功能表”通過改變樣式來顯示和隱藏功能表項目。這些變化都擁有同樣的目的:把使用者的注意力吸引到這些元素上。

JavaScript有如下4種修改CSS的方式:

l 修改元素的style屬性(element.style.margin='10%');

l 改變元素的class或id(element.className='error'),瀏覽器將自動應用那些定義在新的class或id上的樣式;

l 向文檔中寫入新的CSS指令(document.write('<style>.accessibility{display: none}</style>');

l 改變整個頁面的樣式表。

大多數的CSS改變指令碼,都採用修改style屬性或改變class或id的方式。document.write方法只適合用於某些特定的場合以增強頁面的可訪問性。最後,我們很少會改變整個樣式表,因為並非所有的瀏覽器都支援這樣做,而且通常你也只是想改變某些特定元素的樣式。

不管怎麼說,我在範例指令碼中使用了所有4種方法。我們將在本章中逐個研究這些方法及它們適用的場合。

A style屬性

最初也是最廣為人知的修改CSS的方式就是通過所有HTML元素都擁有的style屬性,並且訪問它們的內聯樣式,style對象對每一個內聯的CSS聲明都包含一個對應的屬性。如果你想設定一個元素的CSS屬性margin,使用element.style.margin。如果你想要設定它的CSS屬性color,就使用element.style.color。JavaScript屬性總是擁有一個和CSS屬性相似的名字。

內聯樣式

記住:HTML元素的style屬性讓我們得以訪問該元素的內聯樣式。

讓我們來回顧一些CSS的理論。CSS提供4種方式來給元素定義樣式表。你可以使用內聯樣式,即直接把你的CSS寫在HTML標籤的style屬性中。

<p style="margin: 10%">Text</p>

此外,你可以嵌入、鏈入或引入樣式表。不管用何種方法,因為內聯樣式比其他任何形式的樣式更為明確,內聯樣式能覆蓋那些嵌入、鏈入或引入頁面的樣式表中定義的樣式。因為style屬性可以訪問這些內聯樣式,所以它總是能覆蓋其他的樣式。這是這種方法的巨大優勢。

然而,當你嘗試讀取樣式時,可能遭遇問題。看這個例子:

<p id="test">Text</p>

p#test {

margin: 10%;

}

alert(document.getElementById('test').style.margin);

測試段落並沒有包含任何內聯樣式,margin: 10%是被定義在一個嵌入的(或者鏈入,或者引入的)樣式表中,而它是不可能從style屬性中讀出來的。彈出警告框顯示為空白。

在下一個例子中,彈出警告框將顯示返回結果“10%”,因為margin現在被定義為內聯樣式:

<p style="margin: 10%" id="test">Text</p>

alert(document.getElementById('test').style.margin);

所以,style屬性最適合於設定樣式,而要擷取它們時就沒那麼有用了。後面我們會討論從嵌入頁面的、鏈入的或者引入的樣式表中擷取樣式的方法。

破折號

許多CSS屬性的名字包含一個破折號,例如font-size。然而在JavaScript中,破折號表示相減(minus),因此它不能被用在屬性名稱中。這將給出一個錯誤:

element.style.font-size = '120%';

這是要求瀏覽器從element.style.font裡減去(未定義的)變數size嗎?如果是= '120%'代表什麼意義呢?作為替代,瀏覽器期望一個駝峰格式(camelCase)的屬性名稱:

element.style.fontSize = '120%';

一般規則是從CSS屬性名稱中移除所有的破折號,並且破折號後的字元變為大寫。這樣,margin-left變成了marginLeft,text-decoration變成了textDecoration,而border-left -style變成了borderLeftStyle。

單位

在JavaScript很多數實值型別的值需要一個單位,就像它們在CSS中聲明時那樣。fontSize=120表示什嗎?120像素、還是120磅或者120%?瀏覽器可不知道這些,所以它不會做任何反應。為了闡明你的意圖,單位是必須的。

以setWidth()函數為例,它是實現“XMLHTTP測速計”的動畫效果的核心程式之一:

[XMLHTTP測速計,第70~73行]

function setWidth(width) {

if (width < 0) width = 0;

document.getElementById('meter').style.width = width + 'px';

}

該函數接手一個值,它將改變meter的寬度為這個新值。在經過一個安全檢查以確保該值大於0之後,設定元素的style.width為這個新的寬度值。最後加上'px',因為不這樣的話,瀏覽器可能不知道如何解釋該數值,結果什麼都不做。

不要忘了'px'

忘記在width或height之後附加一個'px'單位是一個常見的CSS修改錯誤。

在CSS的怪癖模式(quirks mode)裡,加上'px'不是必須的,因為瀏覽器遵循舊的規則,把無單位的值視為像素值。本質上這不是一個問題,但很多Web開發人員因此養成了改變寬度或高度值後遺忘加上單位的習慣,當他們工作在CSSstrict 模式(strict mode)下時就遭遇到了問題。

擷取樣式

警告 以下所述內容有瀏覽器安全色性問題。

正如我們所看到的,style屬性不能讀取設定在嵌入、鏈入或引入頁面的樣式表中的樣式。但是因為Web開發人員有時候需要讀取這些樣式,微軟和W3C都提供了訪問非內聯樣式的方式。微軟的解決方案只能工作在Explorer下,而W3C標準可以工作在Mozilla和Opera下。

微軟的解決方案就是currentStyle屬性,它的工作方式像極了style屬性,除了兩件事情:

l 它可以訪問所有樣式,不僅僅是內聯樣式,所以它彙報的是實際應用在元素上的樣式;

l 它是唯讀,你不能通過它設定樣式。

例如:

var x = document.getElementById('test');

alert(x.currentStyle.color);

現在彈出對話方塊顯示元素當前的color樣式,而不管它是在什麼地方被定義的。

W3C的解決方案是window.getComputedStyle()方法,它以相似但文法更為複雜的方式工作:

var x = document.getElementById('test');

alert(window.getComputedStyle(x,null).color);

getComputedStyle()總是返回一個像素值,儘管原來的樣式可能會是50em或11%。

同以前一樣,當我們遭遇不相容的情形時,需要一些代碼分支來滿足所有瀏覽器:

function getRealStyle(id,styleName) {

var element = document.getElementById(id);

var realStyle = null;

if (element.currentStyle)

realStyle = element.currentStyle[styleName];

else if (window.getComputedStyle)

realStyle = window.getComputedStyle(element,null)[styleName];

return realStyle;

}

你可以使用這個函數如下:

var textDecStyle = getRealStyle('test','textDecoration');

記住getComputedStyle()將總是返回一個像素值,而currentStyle保留原來定義在CSS中的單位。

簡寫樣式

警告 以下所述內容有瀏覽器安全色性問題。

不管你是通過style屬性獲得內聯樣式,還是通過剛剛討論的函數擷取其他的樣式,當你嘗試讀取簡寫樣式時,都會遇到問題。

看這個邊框(border)的定義

<p id="test" style="border: 1px solid #cc0000;">Text</p>

因為這是一個內聯樣式,你期望這行代碼可以工作:

alert(document.getElementById('test').style.border);

不幸的是,它不能。不同瀏覽器在彈出對話方塊中顯示的確切的值是不一致的。

l Explorer 6給出的是 #cc0000 1px solid。

l Mozilla 1.7.12給出的是1px solid rgb(204,0,0)。

l Opera 9給出的是1px solid #cc0000。

l Safari 1.3沒有給出任何邊框值。

問題出在border是一個簡寫形式的聲明。它暗中包括了不少於12個樣式:上(top)、左(left)、下(bottom)和右(right)邊框的寬度(width)、風格(style)和顏色(color)。相似地,font聲明是font-size、font-family、font-weight和line-height的簡寫形式,所以它也會展現相似的問題。

rgb()

注意Mozilla使用的特殊的color文法:rgb(204,0,0)。這是傳統的#cc0000的有效替代值。你可以在CSS和JavaScript中任意選擇一個文法使用。

瀏覽器是如何處理這些簡寫形式的聲明呢?上面的例子似乎過於直接;你的直覺應該是期望瀏覽器返回1px solid #cc0000,確保與內聯樣式所定義的一致。不幸的是,簡寫形式的屬性比那還複雜的多。

考慮下面的情形:

p {

border: 1px solid #cc0000;

}

<p id="test" style="border-color: #00cc00;">Test</p>

alert(document.getElementById('test').style.borderRightColor);

所有瀏覽器都彙報正確的顏色,儘管內聯樣式中沒有包含border-right-color而是聲明了border-color。顯然瀏覽器認為右邊框的顏色在設定整個邊框顏色時被設定,這也是合邏輯的。

正如你看到的,瀏覽器必須為這些異常情況制定規則,而且它們已經選擇了略有不同的方式去處理簡寫形式的聲明。在缺乏處理簡寫屬性的明確規範的情況下,很難評判哪個瀏覽器是對還是錯。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.