はじめに
querySelectorAll
で取得した要素に対して、Array関数を利用したいとします。
html.example.html
<html>
<body>
<div class="sample">
sample1
</div>
<div class="sample">
target!
</div>
<div class="sample">
sample3
</div>
<div class="sample">
sample4
</div>
<script>
window.onload = () => {
// 内部テキストが「target!」の要素だけを抽出する
const sampleArray = document.querySelectorAll('.sample')
const target = sampleArray.filter(elem => elem.innerText == 'target!');
}
</script>
</body>
</html>
こんな感じでfilter
を使えば余裕!
・・・かと思いきや。
Uncaught TypeError: sampleArray.filter is not a function at window.onload (example.html:19:32)
エラーが発生しました。アレェ?(Arrayとかけた激ウマギャグ)
説明
querySelectorAllで要素を取得したときの返り値の型はNodeList
というものになります。
Document: querySelectorAll() メソッド - Web API | MDN
そしてこのNodeList
、ドキュメントに「NodeList は Array とは異なります」と明記されています。
そのためfilter
やmap
などの便利な関数が使えません。
対応方法
こうする。
example.html
<html>
<body>
<div class="sample">
sample1
</div>
<div class="sample">
target!
</div>
<div class="sample">
sample3
</div>
<div class="sample">
sample4
</div>
<script>
window.onload = () => {
// 内部テキストが「target!」の要素だけを抽出する
const sampleArray = document.querySelectorAll('.sample')
// const target = sampleArray.filter(elem => elem.innerText == 'target!');
// 下記2つのどちらでも問題なし
const target1 = Array.from(sampleArray).filter(elem => elem.innerText == 'target!');
const target2 = [...sampleArray].filter(elem => elem.innerText == 'target!');
}
</script>
</body>
</html>
書き方は違いますが、やってることとしてはどちらも同じでArray
に変換しているだけです。
個人的には[...sampleArray]
のほうが好み。
おわりに
なんでこんな手間を掛けないといけないんだ・・。
普通にArray関数使える形にしろー!という気持ち。