2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

javascriptで動的に生成した子要素でイベントを発火してほしい

Last updated at Posted at 2022-04-18

はじめに

たまにどうしても使いたくなるけど簡単に調べられないので備忘録的に。
pure javascript でのイベントの割り当てについて書きます。

動的に子要素を生成

配列データを回しながら動的に子要素を生成します。

HTML側がこうなっていて。

<div id="list-target"></div>

動的な生成が以下のようになります。
DOM生成のコストを下げるために文字列で組み立てたものをinnerHTMLで流し込んでいます。

let parentEelement = document.getElementById("list-target");
let childHtmlSource = "";
info.list.forEach((item, index, arrays) => {
  childHtmlSource += "<dl data-uid=\"" + item.uid + "\">"
                   + "<dd>" + item.uid + "</dd>"
                   + "<dd>" + item.name + "</dd>"
                   + "</dl>";
});
parentEelement.innerHTML = childHtmlSource;

この状況で各ddタグにクリックイベントを割り当てたい時のaddEventListnerの付け方です。

イベントの割り当て

方法自体は単純でoptionをtrueにした上で、Event.Targetを判定します。
キャプチャーフェーズとかイベントバブリングとかの説明は省略します。

document.getElementById("list-target").addEventListener("click", (e) => {
  let targetElement = e.target;
  if (targetElement.tagName === "DD") {
    console.log("[%s]", targetElement.parentNode.dataset.uid);
  }
}, true);

なぜこのような方法を採るのかですが、子要素生成後に以下のように書くと幾つかデメリットがあります。
「子要素の数だけaddEventListener()を呼び出すコスト」と「要素の追加・削除した際にイベントの張り直しが必要」というデメリットがあるため上記の方法を採っています。

document.querySelectorAll("#list-target dl").forEach((item, index, arrays) => {
  item.addEventListener("click", (e) => {
    console.log("[%s]", e.currentTarget.dataset.uid);
  }, false);
});
2
3
2

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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?