Posted at

Scala.jsでのremoveEventListener等使用の注意点

More than 3 years have passed since last update.

Scala.jsメモ3つ目

暗黙の型変換周りで躓いたのでメモ


環境

ソフトウェア
バージョン

Scala
2.11.7

Scala.js
0.6.6


まとめ


  • JSに登録するイベントハンドラの型はjs.Function1[dom.Event, Any]にするべき


問題: removeEventListenerが上手く動かない

Scala.jsで,addEventListenerremoveEventListenerを使ったソースコードを書いていた.

元のJavaScriptの仕様通り,Scala.jsでも無名関数だとremoveEventListenerは使えないので,削除するためには,変数にキャプチャする必要がある.というわけで,

import org.scalajs.dom

val callback = (e: dom.Event) => {
println("called")
}
button.addEventListener("click", callback)
button.removeEventListener("click", callback)

というコードを書いてみたが,removeEventListenerが働いてくれない.button.click()を呼び出すと,上のコードは,calledとコンソールに出力してしまう.

これは,addEventListenerremoveEventListenerの呼び出しの際,第二引数が,js.Function1[dom.Event, Any]にキャストされていて,それぞれの呼び出しでcallbackが指すオブジェクトが異なっていたからのようだ.


解決方法

変数にキャプチャする時点でキャストすれば良いので,

import org.scalajs.dom

import scala.scalajs.js

val callback: js.Function1[dom.Event, Any] = (e: dom.Event) => {
println("called")
}
button.addEventListener("click", callback)
button.removeEventListener("click", callback)

とすれば想定通りcallbackを削除してくれる.試してはいないが(動いて満足したので),動作原理からいってjQueryの方も同様の問題(ないし仕様)が発生するのではないかと思う.