W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在我們討論 JavaScript 處理樣式和類的方法之前 —— 有一個(gè)重要的規(guī)則。希望它足夠明顯,但是我們?nèi)匀槐仨毺岬剿?/p>
通常有兩種設(shè)置元素樣式的方式:
<div class="...">
?style
?:?<div style="...">
?。JavaScript 既可以修改類,也可以修改 style
屬性。
相較于將樣式寫入 style
屬性,我們應(yīng)該首選通過 CSS 類的方式來添加樣式。僅當(dāng)類“無法處理”時(shí),才應(yīng)選擇使用 style
屬性的方式。
例如,如果我們動(dòng)態(tài)地計(jì)算元素的坐標(biāo),并希望通過 JavaScript 來設(shè)置它們,那么使用 style
是可以接受的,如下所示:
let top = /* 復(fù)雜的計(jì)算 */;
let left = /* 復(fù)雜的計(jì)算 */;
elem.style.left = left; // 例如 '123px',在運(yùn)行時(shí)計(jì)算出的
elem.style.top = top; // 例如 '456px'
對(duì)于其他情況,例如將文本設(shè)為紅色,添加一個(gè)背景圖標(biāo) —— 可以在 CSS 中對(duì)這些樣式進(jìn)行描述,然后添加類(JavaScript 可以做到)。這樣更靈活,更易于支持。
更改類是腳本中最常見的操作之一。
在很久以前,JavaScript 中有一個(gè)限制:像 "class"
這樣的保留字不能用作對(duì)象的屬性。這一限制現(xiàn)在已經(jīng)不存在了,但當(dāng)時(shí)就不能存在像 elem.class
這樣的 "class"
屬性。
因此,對(duì)于類,引入了看起來類似的屬性 "className"
:elem.className
對(duì)應(yīng)于 "class"
特性(attribute)。
例如:
<body class="main page">
<script>
alert(document.body.className); // main page
</script>
</body>
如果我們對(duì) elem.className
進(jìn)行賦值,它將替換類中的整個(gè)字符串。有時(shí),這正是我們所需要的,但通常我們希望添加/刪除單個(gè)類。
這里還有另一個(gè)屬性:elem.classList
。
elem.classList
是一個(gè)特殊的對(duì)象,它具有 add/remove/toggle
單個(gè)類的方法。
例如:
<body class="main page">
<script>
// 添加一個(gè) class
document.body.classList.add('article');
alert(document.body.className); // main page article
</script>
</body>
因此,我們既可以使用 className
對(duì)完整的類字符串進(jìn)行操作,也可以使用使用 classList
對(duì)單個(gè)類進(jìn)行操作。我們選擇什么取決于我們的需求。
classList
的方法:
elem.classList.add/remove(class)
? —— 添加/移除類。elem.classList.toggle(class)
? —— 如果類不存在就添加類,存在就移除它。elem.classList.contains(class)
? —— 檢查給定類,返回 ?true/false
?。此外,classList
是可迭代的,因此,我們可以像下面這樣列出所有類:
<body class="main page">
<script>
for (let name of document.body.classList) {
alert(name); // main,然后是 page
}
</script>
</body>
elem.style
屬性是一個(gè)對(duì)象,它對(duì)應(yīng)于 "style"
特性(attribute)中所寫的內(nèi)容。elem.style.width="100px"
的效果等價(jià)于我們?cè)?nbsp;style
特性中有一個(gè) width:100px
字符串。
對(duì)于多詞(multi-word)屬性,使用駝峰式 camelCase:
background-color => elem.style.backgroundColor
z-index => elem.style.zIndex
border-left-width => elem.style.borderLeftWidth
例如:
document.body.style.backgroundColor = prompt('background color?', 'green');
前綴屬性
像
-moz-border-radius
和-webkit-border-radius
這樣的瀏覽器前綴屬性,也遵循同樣的規(guī)則:連字符-
表示大寫。
例如:
button.style.MozBorderRadius = '5px'; button.style.WebkitBorderRadius = '5px';
有時(shí)我們想要分配一個(gè)樣式屬性,稍后移除它。
例如,為了隱藏一個(gè)元素,我們可以設(shè)置 elem.style.display = "none"
。
然后,稍后我們可能想要移除 style.display
,就像它沒有被設(shè)置一樣。這里不應(yīng)該使用 delete elem.style.display
,而應(yīng)該使用 elem.style.display = ""
將其賦值為空。
// 如果我們運(yùn)行這段代碼,<body> 將會(huì)閃爍
document.body.style.display = "none"; // 隱藏
setTimeout(() => document.body.style.display = "", 1000); // 恢復(fù)正常
如果我們將 style.display
設(shè)置為空字符串,那么瀏覽器通常會(huì)應(yīng)用 CSS 類以及內(nèi)建樣式,就好像根本沒有這樣的 style.display
屬性一樣。
還有一個(gè)特殊的方法 elem.style.removeProperty('style property')
。所以,我們可以像這樣刪除一個(gè)屬性:
document.body.style.background = 'red'; //將 background 設(shè)置為紅色
setTimeout(() => document.body.style.removeProperty('background'), 1000); // 1 秒后移除 background
用 ?
style.cssText
? 進(jìn)行完全的重寫通常,我們使用
style.*
來對(duì)各個(gè)樣式屬性進(jìn)行賦值。我們不能像這樣的div.style="color: red; width: 100px"
設(shè)置完整的屬性,因?yàn)?nbsp;div.style
是一個(gè)對(duì)象,并且它是只讀的。
想要以字符串的形式設(shè)置完整的樣式,可以使用特殊屬性
style.cssText
:
<div id="div">Button</div> <script> // 我們可以在這里設(shè)置特殊的樣式標(biāo)記,例如 "important" div.style.cssText=`color: red !important; background-color: yellow; width: 100px; text-align: center; `; alert(div.style.cssText); </script>
我們很少使用這個(gè)屬性,因?yàn)檫@樣的賦值會(huì)刪除所有現(xiàn)有樣式:它不是進(jìn)行添加,而是替換它們。有時(shí)可能會(huì)刪除所需的內(nèi)容。但是,當(dāng)我們知道我們不會(huì)刪除現(xiàn)有樣式時(shí),可以安全地將其用于新元素。
可以通過設(shè)置一個(gè)特性(attribute)來實(shí)現(xiàn)同樣的效果:
div.setAttribute('style', 'color: red...')
。
不要忘記將 CSS 單位添加到值上。
例如,我們不應(yīng)該將 elem.style.top
設(shè)置為 10
,而應(yīng)將其設(shè)置為 10px
。否則設(shè)置會(huì)無效:
<body>
<script>
// 無效!
document.body.style.margin = 20;
alert(document.body.style.margin); // ''(空字符串,賦值被忽略了)
// 現(xiàn)在添加了 CSS 單位(px)—— 生效了
document.body.style.margin = '20px';
alert(document.body.style.margin); // 20px
alert(document.body.style.marginTop); // 20px
alert(document.body.style.marginLeft); // 20px
</script>
</body>
請(qǐng)注意:瀏覽器在最后幾行代碼中對(duì)屬性 style.margin
進(jìn)行了“解包”,并從中推斷出 style.marginLeft
和 style.marginTop
。
修改樣式很簡單。但是如何 讀取 樣式呢?
例如,我們想知道元素的 size,margins 和 color。應(yīng)該怎么獲???
style
屬性僅對(duì) "style"
特性(attribute)值起作用,而沒有任何 CSS 級(jí)聯(lián)(cascade)。
因此我們無法使用 elem.style
讀取來自 CSS 類的任何內(nèi)容。
例如,這里的 style
看不到 margin:
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
The red text
<script>
alert(document.body.style.color); // 空的
alert(document.body.style.marginTop); // 空的
</script>
</body>
……但如果我們需要,例如,將 margin 增加 20px 呢?那么我們需要 margin 的當(dāng)前值。
對(duì)于這個(gè)需求,這里有另一種方法:getComputedStyle
。
語法如下:
getComputedStyle(element, [pseudo])
?element
?
需要被讀取樣式值的元素。
?pseudo
?
偽元素(如果需要),例如 ?::before
???兆址驘o參數(shù)則意味著元素本身。
結(jié)果是一個(gè)具有樣式屬性的對(duì)象,像 elem.style
,但現(xiàn)在對(duì)于所有的 CSS 類來說都是如此。
例如:
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
<script>
let computedStyle = getComputedStyle(document.body);
// 現(xiàn)在我們可以讀取它的 margin 和 color 了
alert( computedStyle.marginTop ); // 5px
alert( computedStyle.color ); // rgb(255, 0, 0)
</script>
</body>
計(jì)算值和解析值
在 CSS 中有兩個(gè)概念:
- 計(jì)算 (computed) 樣式值是所有 CSS 規(guī)則和 CSS 繼承都應(yīng)用后的值,這是 CSS 級(jí)聯(lián)(cascade)的結(jié)果。它看起來像 ?
height:1em
? 或 ?font-size:125%
?。- 解析 (resolved) 樣式值是最終應(yīng)用于元素的樣式值。諸如 ?
1em
? 或 ?125%
? 這樣的值是相對(duì)的。瀏覽器將使用計(jì)算(computed)值,并使所有單位均為固定的,且為絕對(duì)單位,例如:?height:20px
? 或 ?font-size:16px
?。對(duì)于幾何屬性,解析(resolved)值可能具有浮點(diǎn),例如:?width:50.5px
?。很久以前,創(chuàng)建了
getComputedStyle
來獲取計(jì)算(computed)值,但事實(shí)證明,解析(resolved)值要方便得多,標(biāo)準(zhǔn)也因此發(fā)生了變化。
所以,現(xiàn)在
getComputedStyle
實(shí)際上返回的是屬性的解析值(resolved)。
?
getComputedStyle
? 需要完整的屬性名我們應(yīng)該總是使用我們想要的確切的屬性,例如
paddingLeft
、marginTop
或borderTopWidth
。否則,就不能保證正確的結(jié)果。
例如,如果有
paddingLeft/paddingTop
屬性,那么對(duì)于getComputedStyle(elem).padding
,我們會(huì)得到什么?什么都沒有,或者是從已知的 padding 中“生成”的值?這里沒有標(biāo)準(zhǔn)的規(guī)則。
還有其他不一致的地方。例如,在下面這個(gè)例子中,某些瀏覽器(Chrome)會(huì)顯示
10px
,而某些瀏覽器(Firefox)則沒有:
<style> body { margin: 10px; } </style> <script> let style = getComputedStyle(document.body); alert(style.margin); // 在 Firefox 中是空字符串 </script>
應(yīng)用于 ?
:visited
? 鏈接的樣式被隱藏了!可以使用 CSS 偽類
:visited
對(duì)被訪問過的鏈接進(jìn)行著色。
但
getComputedStyle
沒有給出訪問該顏色的方式,因?yàn)槿绻试S的話,任意頁面都可以通過在頁面上創(chuàng)建它,并通過檢查樣式來確定用戶是否訪問了某鏈接。
JavaScript 看不到
:visited
所應(yīng)用的樣式。此外,CSS 中也有一個(gè)限制,即禁止在:visited
中應(yīng)用更改幾何形狀的樣式。這是為了確保一個(gè)不好的頁面無法檢測(cè)鏈接是否被訪問,進(jìn)而窺探隱私。
要管理 class,有兩個(gè) DOM 屬性:
className
? —— 字符串值,可以很好地管理整個(gè)類的集合。classList
? —— 具有 ?add/remove/toggle/contains
? 方法的對(duì)象,可以很好地支持單個(gè)類。要改變樣式:
style
? 屬性是具有駝峰(camelCased)樣式的對(duì)象。對(duì)其進(jìn)行讀取和修改與修改 ?"style"
? 特性(attribute)中的各個(gè)屬性具有相同的效果。要了解如何應(yīng)用 ?important
? 和其他特殊內(nèi)容 —— 在 MDN 中有一個(gè)方法列表。style.cssText
? 屬性對(duì)應(yīng)于整個(gè) ?"style"
? 特性(attribute),即完整的樣式字符串。要讀取已解析的(resolved)樣式(對(duì)于所有類,在應(yīng)用所有 CSS 并計(jì)算最終值之后):
getComputedStyle(elem, [pseudo])
? 返回與 ?style
? 對(duì)象類似的,且包含了所有類的對(duì)象。只讀。編寫一個(gè)函數(shù) showNotification(options)
:該函數(shù)創(chuàng)建一個(gè)帶有給定內(nèi)容的通知 <div class="notification">
。該通知應(yīng)該在 1.5 秒后自動(dòng)消失。
參數(shù):
// 在窗口的右上角附近顯示一個(gè)帶有文本 "Hello" 的元素
showNotification({
top: 10, // 距窗口頂部 10px(默認(rèn)為 0px)
right: 10, // 距窗口右邊緣 10px(默認(rèn)為 0px)
html: "Hello!", // 通知中的 HTML
className: "welcome" // div 的附加類(可選)
});
使用 CSS 定位在給定的 top/right 坐標(biāo)處顯示元素。源文檔已經(jīng)提供了必要的樣式。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: