14
20

More than 5 years have passed since last update.

【JavaScript】getElementsByClassName() メソッドでハマった件

Posted at

なぜ?

何気なくgetElementsByClassName()メソッドを利用して、
任意のクラス名を含む全ての要素を取得した後に、反復処理を行おうと思ったのですが、、、
あれ?動かない?

動作しなかったコード
var checkBoxes = document.getElementsByClassName("checkBox");
for(var key in checkBoxes){
    if(checkBoxes[key].classList.contains("checked")){
        checkBoxes[key].checked = true;
    }
}

盛大に勘違いしていたのですが、
getElementsByClassName()メソッドが返す値は配列だと思っていたら、実は違った!
getElementsByClassName()は、配列に似ていますが実際には配列ではないHTMLcollectionオブジェクトを返します。
配列ではないので、例えばforEachみたいな便利な配列メソッドを呼び出すことはできません。
また、 for/inを使用してHTMLCollectionを反復処理することはできません。
(※現在のブラウザ環境では動作するみたいです。)

自分の環境では、for/inを使用した反復処理は動作したのですが、
HTMLCollectionはclassListプロパティを持たないので、要素に紐付いたclass属性のリストを返すelement.classListが使用できませんでした。

解決策

Array.prototypeを利用する

配列に変換
var checkBoxes = document.getElementsByClassName("checkBox");
var array = Array.prototype.slice.call(checkBoxes);//配列に変換

上記のようにArray.prototypeを使い配列に変換することで、解決しました。

ちなみに
getElementsByClassName()は、Internet Explorer8以下、Firefox2以下のブラウザでは使えないそうです。

まとめ

  • getElementsByClassName()メソッドが返す値は配列ではなく、HTMLCollection
  • HTMLCollectionは配列系のメソッドが使用できない

普段、jQueryを使い慣れているせいなのか、
JavaScriptでDOM操作するとつまづくことが多い...
目指せ!脱jQuery化!

14
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
20