iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0
自我挑戰組

JavaScript老學徒筆記—馬步篇系列 第 24

【Day23】我變我變我變變變:如何改變HTML元素的樣式

「DOM API定義了JavaScript存取、改變HTML架構、內容、樣式的方法,甚至對節點綁定的事件。」

前面幾篇提到了JavaScript改變HTML架構與內容的方法,這一篇我們來談談怎麼改變HTML的樣式。

再來看一下前面提到的「前端三要素」:

  • HTML負責網頁的結構與內容
  • CSS負責網頁的外觀與樣式
  • JavaScript負責網頁的互動與行為

樣式是由CSS負責,所以當我們想要改變HTML的樣式,當然就是要用JavaScript來處理CSS這一塊,而這都要先從選取到某個節點開始。

  • 選取HTML元素,直接修改style屬性
  • 透過className屬性來修改style樣式。
  • 用classList屬性,透過刪除或新增class來修改style樣式
  • 用setAttribute()來更改class屬性

直接修改HTML元素的style

使用JavaScript直接修改HTML元素的style,因為這種方式是透過DOM API直接修改元素的行內樣式,樣式的優先權會比其他樣式的寫法高出許多。

//可以在'string'中指定許多種樣式,樣式之間用;隔開就
node.style.cssText = 'string';

//也可以把某個樣式,例如字型大小單獨挑出來
node.style.fontSize = '24px';

我們試著把黃藥師寫的詩,用JavaScript來改變其樣式:

<div class="style1" style="color: red; font-size: 45px; border: 3px solid;width: 400px;">
  桃花影落飛神劍,
</div>
<div class="style2" style="color: yellow;font-size: 45px;text-decoration:underline;">
  碧海潮生按玉簫
</div>

看看下面的JavaScript,cssText將要改的樣式寫在同一行,而且會完全蓋掉本來寫在style1的全部樣式,我在cssText裡面並沒有輸入border的參數,而本來寫在行內樣式的border卻被完全清除了,最後網頁上呈現的結果並沒有border。

如果用「style.CSS屬性名稱」的方式,就可以針對想要改變的屬性來做處理。唯一要注意的是有些CSS屬性名稱中間有 - 的破折號,如font-size、font-weight… 等等屬性,但是在JavaScript的變數及物件屬性名稱是不允許使用 - 破折號,這時屬性名稱就要改成「駝峰式」寫法,如fontSize。

var el1 = document.querySelector(".style1").style.cssText = 'font-size: 24px; color: green;';
var el2 = document.querySelector(".style2");
el2.style.fontSize = "16px";
el2.style.color = "blue";

透過className屬性來修改style樣式

透過修改HTML「行內樣式」來調整網頁的外觀,雖然很方便,但是我們說過「CSS負責網頁的外觀與樣式」,如果老是透過「行內樣式」來調整網頁外觀,就做不到HTML、CSS、JavaScript三者「關注點分離」,而且實務上,大多是以HTML連結CSS檔案的方式來設定網頁的外觀與樣式。

那要如何透過修改HTML標籤的class屬性,來改變元素的樣式呢?

JavaScript提供了className的屬性來修改HTML元素的class。

node.className = '元素的class名稱'

我們一樣用黃藥師的詩來講解,我們給它兩個class屬性,分別為 redfont與bigtitle。

<h1 class="redfont bigtitle">桃花影落飛神劍,碧海潮生按玉簫</h1>

以下為外部CSS檔的內容:

.redfont {
  color: red;
}
.bigtitle {
  font-size: 40px;
}
.bluefont {
  color: blue;
}

先選取節點,然後用className的方法,把 <h1> 標籤的本來的 class 取代為 bluefont,我們會發現,除了本來的redfont 之外,連 bigtitle 也被清除掉了。所以如果本來HTML標籤有設定多組 class 屬性,用 className 的方法並不會保留其他沒有被修改的屬性,而是整個 class 被清空,再以className 新增的屬性取代。

var el = document.querySelector('.redfont');
el.className = 'bluefont'

用classList屬性,透過刪除或新增class來修改style樣式

classList 與 className 不同之處在於不能直接修改,而是必須透過 claaList.add() 與 classList.remove() 來增加與刪減 HTML 標籤的 class 屬性,如果你的 HTML 標籤有 red 與 big 兩個 class 樣式,你想把 red 改成 green,必須先 classList.remove(red) ,把 red 這個 class 移除,然後再 classList.add(green) ,把 green 這個 class 加入。

<h1 class="redfont bigtitle">桃花影落飛神劍,碧海潮生按玉簫</h1>

這是CSS檔:

.redfont {
  color: red;
}
.bigtitle {
  font-size: 40px;
}
.greenfont {
  color: green;
}

而這是JavaScript,用來改變 <h1> 標籤內的class,redfont會被greenfont置換,而bigtitle會保留下來。

var el = document.querySelector('.redfont');
el.classList.remove('redfont');
el.classList.add('greenfont');

還有一個切換 class 的方法,那就是el.classList.toogle('class名稱') ,當所選的元素沒有這個class樣式的時候,就新增這個樣式;如果已經有這個 class 樣式的時候,就會變成刪除它。

var el = document.querySelector('.redfont');
el.classList.toggle('redfont'); //現在是增加
el.classList.toggle('redfont'); //現在是刪除

用setAttribute()來更改class屬性

還有一種方式可以用來更改 HTML 元素的 class 屬性,但是它的使用範圍更廣泛一些:

element.setAttribute('屬性名稱','屬性值');
//屬性名稱可以是 class、 id、 href
//屬性值對應的分別是 class名稱、 id名稱 及 網址 

讓我們來看看怎麼做:

<h1 class="redfont bigtitle">桃花影落飛神劍,碧海潮生按玉簫</h1>
.redfont {
  color: red;
}
.bigtitle {
  font-size: 40px;
}
.bluefont {
  color: blue;
}
var el = document.querySelector('.redfont');
el.setAttribute('class','bluefont');

用 setAttribute() 來修改 HTML 元素的 class ,跟className 一樣,也是會先把 class 清空,再用新增的class 設定值取代,所以 bigtitle 這個 class 也會被清除掉。

以上就是幾種修改HTML元素樣式的方法。


上一篇
【Day22】在網頁中插入HTML標籤的實務做法
下一篇
【Day24】派一個Spy到網頁中竊聽—事件監聽
系列文
JavaScript老學徒筆記—馬步篇35

尚未有邦友留言

立即登入留言