IEでのNodeList.prototype.forEach()の扱い

2021-04-24

概要

私たちはJavaScriptでDOM操作する際、以下のように取得したりします。

// HTMLElementオブジェクトを取得
document.querySelector('.target')
// 複数Elementを格納しているNodeListを取得
document.querySelectorAll('.targets')

ですが、後者であるNodeListはforEach処理をしようとすると、Internet Explorerにてエラーになります。サポートされていないからです。
https://developer.mozilla.org/ja/docs/Web/API/NodeList

では、どのように対応すればよいのでしょう。

解決策

NodeList.prototype.forEach()が対応していないのであれば、新たな配列を作成すれば良い、ということになります。

Array.prototype.slice.call(arguments)

魔法の言葉に見えます。これで、配列に変換できます。
callでthisの対象をargumentsに仕向けて、sliceメソッドでコピーしているという感じでしょうか。

const nodelist = document.querySelectorAll('.targets')
const list = Array.prototype.slice.call(nodelist)
list.forEach(function(item) {
  // 処理
})

短縮系として、[].slice.call(arguments)とすることも可能です。

Array.from(arguments)

引数に配列に変換する配列のようなオブジェクトまたは反復可能オブジェクトを入れると、新しい配列のインスタンスを作成できます。

const nodelist = document.querySelectorAll('.targets')
const list = Array.from(nodelist)

ちなみにArray.from()はInternetExplorerにてサポートされていませんので、Polyfillを入れる必要があります。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from

スプレッド構文

配列を複製できます。

const nodelist = document.querySelectorAll('.targets')
const list = [...nodelist]

挙動としては、[].slice()のような動きになるでしょうか。

このスプレッド構文はES6より導入された構文ですので、InternetExplorerには解釈できません。
なので、Babelなどの下位互換コードに変換するツールを使用する必要があります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax

おっと、誤解しないように…

中には「forEachメソッドはInternetExplorerに対応していないのでしょうか」と聞いてくる方がいらっしゃいます。

違います。

NodeListを展開する際のforEachがサポートされていないだけで、配列オブジェクトに対して使用するには問題ありません。

// 以下問題なく動作する
['item01', 'item02', 'item03'].forEach(function(item) {
  console.log(item)
})

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

結論

InternetExplorer対応、いつまですればよいのでしょうか。
…ともかく、NodeListを使用する際は注意する必要がありますね。

いくつかの解決策を提示しましたが、他にも対応できる方法が見つかるかもしれません。

運営について

Natural Tearoomはシステム開発会社フロントエンドエンジニアがんちゃんが運営するメディアです。
フロントエンド技術を中心に発信しています。

· プライバシーポリシー

SNS

© 2021 天然珈琲店