2022年6月へ

[JavaScript] 複数の要素のClassNameを消去する。

公開日:

最終更新日:

要約

本記事では、JavaScriptのgetElementsByClassNameで取得した複数の要素から特定のクラス("active")を削除する際の問題点と解決策について説明しています。通常のforループやforEachでは要素数の変化により正しくクラスが削除されませんが、whileループを用いてリアルタイムに要素数を確認しながら処理する方法を紹介しています。よりスマートな対処法やjQueryでのまとめてクラス削除にも言及しています。

  • JavaScript
  • DOM操作
  • クラス削除
  • getElementsByClassName
  • HTMLCollection
  • ループ処理
  • forループ
  • whileループ
  • jQuery
  • プログラミング

下のような HTML(&JavaScript)がある。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <div id="Main">
      <div class="item active"></div>
      <div class="item active"></div>
      <div class="item active"></div>
      <div class="item active"></div>
    </div>
    <script type="text/javascript">

const Elements = document.getElementsByClassName("active")
for(let i = 0; i < Elements.length; i++){
  const Element = Elements[i]
  Element.classList.remove("active")
}
console.log(Elements);

</script>
</body>
</html>

script の内容は,active クラスをもつ div 要素を取得し,それらから active クラスを削除することです。

最後に Elements 変数を出力します。

しかし,これをブラウザ上で実行すると,コンソールでは次のように表示されます。

HTMLCollection (2)
0 
<div class="item active"></div>
1 
<div class="item active"></div>

ここで注意したいことは,Elements 変数の中にある div 要素が 2つしかないことと,active クラスをもつ要素が残っていること。

コードの中を修正し,より確認します。

const Elements = document.getElementsByClassName("active")
for(let i = 0; i < Elements.length; i++){
  const Element = Elements[i]
  Element.classList.remove("active")
  Elements.length;
}

実行すると次の値が返ってきます。

3
2

ループ中にて,getElementByClassName で取得した要素数が変化しています。

そのため, i で取得している要素にズレが生じ,classList.remove() が正しく働いていないのでしょう。

forEach も試しましたが同じ結果でした。

そこで,次のように while を使うと結果が変わります。

const Elements = document.getElementsByClassName("active")
let i = 0;
while(Elements.length !== 0){
  const Element = Elements[i]
  Element.classList.remove("active")
}
console.log(Elements)

console.log の内容は次。

HTMLCollection (0)
プロパティなし

これで,active クラスをもつ要素がすべて削除されたことを確認できます。

しかし,もっとスマートな方法がありそうですが,どうでしょう。

jQuery だったら,まとめてクラス削除できるのですが・・・。