IE,Edgeでdocument.querySelectorAllをforEachする方法
2019/06/15

javascriptで複数の要素に対して、なにかしらの処理を行いたいときに、querySelectorAllを使って、私はよくこのように書いています。

const hoges = document.querySelectorAll('.hoge');
hoges.forEach((el) => {
  // なにかしらの処理
});

.hoge 要素をすべて取得して、それぞれになにかしらの処理を行う。
至って自然な書き方ですが、実はこれ、、IE,Edgeだとエラーが発生します。

Object doesn't support property or method 'forEach'

querySelectorAllforIE

「変数hogesにforEachというメソッドがありません」 というエラーが出てしまう。

原因

querySelectorAllNodeListというオブジェクトを返します。

console.log(document.querySelectorAll('.hoge'));
> NodeList(3) [div.hoge, div.hoge, div.hoge]

MDNのサイト( https://developer.mozilla.org/ja/docs/Web/API/NodeList )に以下のように書いてありました。

NodeList は Array とは異なりますが、 forEach() メソッドで処理を反復適用することは可能です。 Array.from() を使うことで Array に変換することができます。

ただし、古いブラウザーでは NodeList.forEach() も Array.from() 実装されていない場合があります。これらの制限は Array.prototype.forEach() を使うことで回避することが可能です (この文書に詳しく書かれています)。

そう、古いブラウザーでは NodeList.forEach()に対応していなかったのです!

解決策

Array.fromを使って、配列にしてからforEachをする。

const hoges = Array.from(document.querySelectorAll('.hoge'));
hoges.forEach((el) => {
  // なんらかの処理
});

これで、IE,Edgeでも動作するようになります。

※ ES6を導入していない場合は以下のように書く必要があります。

var hoges = document.querySelectorAll('.hoge');
Array.prototype.forEach.call(hoges, function (el) {
  // なんらかの処理
});

まとめ

IE11とEdgeという無視することができないブラウザで対応していないとは、、、
(2017年9月26日にリリースされた EdgeHTML 16.16299 以降ではforEachに対応しているそうです。)

今後は、Array.from(document.querySelectorAll())で習慣つけていく必要がありそうです。