如果使用 scala 函数,scalajs removeEventListener 不工作
scalajs removeEventListener not working if using a scala function
此代码未按预期运行(按下某个键时仍会执行 keydown
功能):
import org.scalajs.dom.raw.Event
import org.scalajs.dom.{console, document}
import scala.scalajs.js
def keydown(e: Event) { console.log(e) }
document.addEventListener("keydown", keydown)
document.removeEventListener("keydown", keydown)
此修改后的代码确实按预期工作:
def keydown_(e: Event) { console.log(e) }
val keydown: js.Function1[Event, Unit] = (e: Event) => keydown_ _
document.addEventListener("keydown", keydown)
document.removeEventListener("keydown", keydown)
为什么会这样?
是否可以删除这个额外的样板代码行?
Scala Functions 和 JS Functions 是不同的类型,需要相互转换。这是隐式为您完成的,但是每次调用转换时,此转换都会创建一个新的 JS 函数实例。
所以多次调用转换,即使是隐式调用,每次都会得到不同的JS Function实例。即使这些实例包装了相同的 Scala 函数,浏览器也不知道这一点。为了 removeEventListener
,您需要为它提供与您传递给 addEventListener
完全相同的 JS 函数引用,这就是为什么您的 val
示例有效但 def
无效的原因t.
此代码未按预期运行(按下某个键时仍会执行 keydown
功能):
import org.scalajs.dom.raw.Event
import org.scalajs.dom.{console, document}
import scala.scalajs.js
def keydown(e: Event) { console.log(e) }
document.addEventListener("keydown", keydown)
document.removeEventListener("keydown", keydown)
此修改后的代码确实按预期工作:
def keydown_(e: Event) { console.log(e) }
val keydown: js.Function1[Event, Unit] = (e: Event) => keydown_ _
document.addEventListener("keydown", keydown)
document.removeEventListener("keydown", keydown)
为什么会这样? 是否可以删除这个额外的样板代码行?
Scala Functions 和 JS Functions 是不同的类型,需要相互转换。这是隐式为您完成的,但是每次调用转换时,此转换都会创建一个新的 JS 函数实例。
所以多次调用转换,即使是隐式调用,每次都会得到不同的JS Function实例。即使这些实例包装了相同的 Scala 函数,浏览器也不知道这一点。为了 removeEventListener
,您需要为它提供与您传递给 addEventListener
完全相同的 JS 函数引用,这就是为什么您的 val
示例有效但 def
无效的原因t.