LoginSignup
0
0

More than 3 years have passed since last update.

【JS】querySelectorAll()メゾッド使用時にaddEventListener()メゾットが動かなかった

Last updated at Posted at 2020-03-20

問題

querySelectorAll()メゾッドでセレクタを指定して、addEventListener()メゾッドでクリックイベントを仕込もうとしたときです。

main.js
  const target = document.querySelectorAll('nav a');
  const closeNav = function () {
    const close = document.getElementById('global-nav');
    close.classList.toggle('nav-open');
  };
  target.addEventListener('click', closeNav);

addEventListener()が動かない…

Consoleではこのように怒られています。
スクリーンショット 2020-03-21 2.25.32.png

Uncaught TypeError: target.addEventListener is not a function

どうやらtarget.addEventListenerが関数(function)として認識されていないようです。

querySelector()ではうまく動いたのに…

原因

まずquerySelectorAll()メゾッドのリファレンスを読むと

Document の querySelectorAll() メソッドは、与えられた CSS セレクターに一致する文書中の要素のリストを示す静的な (生きていない) NodeList を返します。

とあります。
文書中の要素のリストを示す静的な (生きていない) NodeList を返す…

さらに、querySelectorAll()メゾッドの返値というNodeListを調べると

NodeList オブジェクトはノードの集合であり、 Node.childNodes などのプロパティや document.querySelectorAll() などのメソッドの返値として用いられます。

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

とありました。
このことから、querySelectorAll()の返値は配列ではないがリスト状になっており、forEach()メゾッドを使えば処理することができるという解釈にいたりました。

解決

main.js
  const targetList = document.querySelectorAll('nav a');
  const closeNav = function () {
    const close = document.getElementById('global-nav');
    close.classList.toggle('nav-open');
  };
  targetList.forEach(function (target) {
    target.addEventListener('click', closeNav);
  });

まずquerySelectorAll()メゾッドの返値はリストということで、targetListという変数名にしました。
そして、targetList内のひとつひとつの要素にaddEventListener()メゾッドが実行されるように、forEach()メゾッドでtargetListを回しました。

無事、エラーが解消され、望んだ動きをしてくれるようになりました。

まとめ

  • querySelectorAll()メゾッドは配列ではないがリスト状のNodeListを返す。
  • forEach()メゾッドでリストの中身ひとつひとつに処理をあてることができる。

参照

0
0
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
0
0