💡

あるhtml要素からJavaScriptのイベントを全て削除したい

2023/10/29に公開

課題

あるelementにJavaScriptのイベントリスナーが登録されている。
そのeventを全て削除したい。(そして上書きしたい)

経緯

既存のコードのclickイベントの動作を変更する必要があった。

clickイベントを定義しているコードは広範に共通化されている。影響範囲が大きい。この共通ファイルを触りたくない。影響範囲の小さい個別のファイルで挙動を上書きしたい。

addEventListener()で追記してもイベントが増えるだけ。上書きできない\(^o^)/

解決策

elementをcloneNode()で複製して、該当のDOMをゴッソリ入れ替える方法をとった。
複製されたノードは、イベントリスナーで登録されたイベントを複製しません。

下記が実装例。

<button id="btn">ボタンだ</button>
<script>
// 元のボタン
const btn = document.getElementById("btn");

// 消したいイベント達
btn.addEventListener("click", () => {
    alert("あああ")
})
btn.addEventListener("click", () => {
    alert("いいい")
})

// ボタンをクローンで複製
const clonedBtn = btn.cloneNode(true);
// 元のボタンをクローンで置き換える
btn.replaceWith(clonedBtn)

// 新たに設定したいイベント
clonedBtn.addEventListener("click", () => {
    alert("ううう")
})
</script>

これでbutton要素に紐付いたclickイベントから、最初の2つのイベント消去され、最後のイベントで上書きされました。

補足

removeEventListener()

削除するイベントを指定してremoveEventListener()で削除するのが、王道的なやり方かと思います。
出来れば私もremoveEventListener()を使いたかった。

例えば、以下のコードは『あああ』のアラートを『いいい』で上書きできます。

<button id="btn">ボタンだ</button>
<script>
// ボタン
const btn = document.getElementById("btn");

// 削除したいイベント
const aaa = () => {
    alert("あああ")
}
btn.addEventListener("click", aaa)
btn.removeEventListener("click", aaa)

// 上書きしたいイベント
btn.addEventListener("click", () => {
    alert("いいい")
})
</script>

しかし、このやり方は、addEventListener()第二引数に無名関数を使用している場合、使えません。イベントリスナーの関数名が設定されているときだけ使えます。
上記の例では、第二引数の関数名にaaaが設定されているから動作します。

今回、私が直面したコードにおいては、イベントリスナーの関数名が別ファイルのjsファイルに定義されていました。だから、removeEventListener()を使えませんでした。

上書きできない

残念ながら下記のようなコードでは、『あああ』のアラートを削除することは出来ません。上書き駄目。

<button id="btn">ボタンだ</button>
<script>
// ボタン
const btn = document.getElementById("btn");

// 消したいイベント
btn.addEventListener("click", () => {
    alert("あああ")
})
// 上書きしたいイベント
btn.addEventListener("click", () => {
    alert("いいい")
})
</script>

参考

当記事を書くにあたって、参考にしたサイト達。

https://kajindowsxp.com/js-event-remove/

https://stackoverflow.com/questions/9251837/how-to-remove-all-listeners-in-an-element

https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener

https://developer.mozilla.org/ja/docs/Web/API/EventTarget/removeEventListener

https://developer.mozilla.org/ja/docs/Web/API/Node/cloneNode

https://developer.mozilla.org/ja/docs/Web/API/Element/replaceWith

もっとイケてるやり方をご存知の方は教えて下さい。

Discussion