LoginSignup
13
10

More than 5 years have passed since last update.

NodeListにfilterをかけたくなったら

Posted at

jQueryが諸事情で使えない(というか外部ライブラリ全般ページに呼び込みたくない)案件があって、document.querySelectorAll('.nyan') でとれたDOMの中から(プログラム上)任意のdata値のvalueだけを持つものが欲しい時があり、少し面倒だったので忘備録。

<ul>
  <li class="nyan" data-nyan="1">nyan</li>
  <li class="nyan" data-nyan="2">nyan :)</li>
  <li class="nyan" data-nyan="3">nyan :(</li>
  <li class="nyan" data-nyan="4">nyan ;)</li>
  <li class="nyan" data-nyan="5">nyan ;(</li>
</ul>

上記のDOMから data-nyan が 3の値が欲しい場合、

const nyans = document.querySelectorAll('.nyan');

const resultNyan = nyans.filter((element, index) => {
  return element.dataset['nyan'] === '3';
});

// Error => Uncaught TypeError: nyans.filter is not a function

と怒られてしまう。
どうやらNodeListには列挙したりするイテレータはあるものの、特定の要素をつまみ出すようなメソッドは備わってないとのこと。

ということで、純粋にNodeListに対してfilterを使いたい場合、@type {NodeList} => {Array} にしてやる必要がある。

const nyans = document.querySelectorAll('.nyan');

const convertedTypeArrayNyan = [].map.call(nyans, (element) => {
  return element;
});

const resultNyan = convertedTypeArrayNyan.filter((element, index) => {
  return element.dataset['nyan'] === '3';
});

// resultNyan[0].outerHTML: "<li class="nyan" data-nyan="3">nyan :(</li>"

とスッキリいく。

中には Array.prototype.slice.call使ったりもあったが、「Arrayライクなリスト型のものを、Arrayとして再配列(マッピング)する」という意味では Array.prototype.mapのほうがしっくり来たのでこっちを使っている(まぁNodeListの余分な物を削ぎ落とすってことでsliceも考えられなくはないが)。

ということでNodeListでListなんだから、もう少しそこら辺のメソッド拡張してよEcmaさんって雑な感想をもった。

13
10
6

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
13
10