あるhtml要素からJavaScriptのイベントを全て削除したい
課題
ある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>
参考
当記事を書くにあたって、参考にしたサイト達。
もっとイケてるやり方をご存知の方は教えて下さい。
Discussion