ScalaJS 上的可拖动 removeEventListener 不起作用
draggable on ScalaJS removeEventListener does not work
基于该 js 演示:http://jsfiddle.net/wfbY8/737/
class Draggable(element: HTMLDivElement) {
var offX: Double = 0
var offY: Double = 0
val divMove = (e:MouseEvent) => {
//element.style.position = 'absolute';
element.style.top = (e.clientY-offY) + "px"
element.style.left = (e.clientX-offX) + "px"
}
val mouseDown = (e:MouseEvent) => {
offY = e.clientY - element.offsetTop
offX = e.clientX - element.offsetLeft
window.addEventListener("mousemove", divMove, useCapture = true)
println("added")
}
val mouseUp = (e:MouseEvent) => {
window.removeEventListener("mousemove", divMove, useCapture = true)
println("removed")
}
def addListeners(){
element.addEventListener("mousedown", mouseDown, useCapture = false)
window.addEventListener("mouseup", mouseUp, useCapture = false)
}
addListeners()
}
从客户端代码我使用它是这样的:
val panelElem = document.getElementById(COMPONENT_ID).asInstanceOf[HTMLDivElement]
if (draggable == null) {
draggable = new Draggable(panelElem)
}
我在日志中看到 "added" 和 "removed"。但是元素仍然可以移动(当我移动鼠标而不按下它时)对我来说就好像我没有从侦听器(在 mouseUp 上)删除 mousemove 事件一样。
不知道为什么..
发生这种情况是因为您有效地将 Scala 函数(lambda)分别转换为 add
和 remove
的 JS 函数。在 Scala.js 中,Scala 函数会根据需要隐式 转换 为 JS 函数。但是,每次转换都会产生不同的 JS 函数(它没有相同的 identity)。因此,您要删除的功能与您添加的功能不同,当然这没有任何效果。
您可以通过强制提前进行转换来解决此问题,这样您就可以添加和删除相同的函数。为此,只需将显式类型添加到您的函数 val
s 作为 JS 函数:
val divMove: js.Function1[MouseEvent, Unit] = (e:MouseEvent) => {
...
}
这样,从 Scala 函数到 JS 函数的转换只发生一次,并且是给 add
- 和 removeEventListener
.
的同一个 JS 函数
基于该 js 演示:http://jsfiddle.net/wfbY8/737/
class Draggable(element: HTMLDivElement) {
var offX: Double = 0
var offY: Double = 0
val divMove = (e:MouseEvent) => {
//element.style.position = 'absolute';
element.style.top = (e.clientY-offY) + "px"
element.style.left = (e.clientX-offX) + "px"
}
val mouseDown = (e:MouseEvent) => {
offY = e.clientY - element.offsetTop
offX = e.clientX - element.offsetLeft
window.addEventListener("mousemove", divMove, useCapture = true)
println("added")
}
val mouseUp = (e:MouseEvent) => {
window.removeEventListener("mousemove", divMove, useCapture = true)
println("removed")
}
def addListeners(){
element.addEventListener("mousedown", mouseDown, useCapture = false)
window.addEventListener("mouseup", mouseUp, useCapture = false)
}
addListeners()
}
从客户端代码我使用它是这样的:
val panelElem = document.getElementById(COMPONENT_ID).asInstanceOf[HTMLDivElement]
if (draggable == null) {
draggable = new Draggable(panelElem)
}
我在日志中看到 "added" 和 "removed"。但是元素仍然可以移动(当我移动鼠标而不按下它时)对我来说就好像我没有从侦听器(在 mouseUp 上)删除 mousemove 事件一样。
不知道为什么..
发生这种情况是因为您有效地将 Scala 函数(lambda)分别转换为 add
和 remove
的 JS 函数。在 Scala.js 中,Scala 函数会根据需要隐式 转换 为 JS 函数。但是,每次转换都会产生不同的 JS 函数(它没有相同的 identity)。因此,您要删除的功能与您添加的功能不同,当然这没有任何效果。
您可以通过强制提前进行转换来解决此问题,这样您就可以添加和删除相同的函数。为此,只需将显式类型添加到您的函数 val
s 作为 JS 函数:
val divMove: js.Function1[MouseEvent, Unit] = (e:MouseEvent) => {
...
}
这样,从 Scala 函数到 JS 函数的转换只发生一次,并且是给 add
- 和 removeEventListener
.