Scala.js:使用addEventListener为对象添加事件

7
在JavaScript中,addEventListener()方法的使用方式如下:
object.addEventListener("click", myScript);

在Scala.js中:我有一个画布,我只想在画布上监听点击事件,而不是整个文档。在Scala.js.dom库中,addEventListener被定义为:
 def addEventListener(`type`: String, listener: js.Function1[Event, _], useCapture: Boolean = ???): Unit = ???

我不确定"useCapture"是什么意思。但我尝试了一下:
dom.document.getElementById("canvas").addEventListener("click", {
(e:dom.MouseEvent) => { /*do something*/ }
}, false)

我收到的错误信息:

found   : org.scalajs.dom.MouseEvent => Unit
required: scala.scalajs.js.Function1[org.scalajs.dom.Event, _]

请问「useCapture」是什么意思,如何在 Scala.js 中正确使用 addEventListener?


关于 useCapture,以下代码片段来自 Mozilla 文档: “表示此类型的事件将首先分派给已注册的侦听器,然后再分派给 DOM 树中位于其下方的任何 EventTarget。” - Matthias Braun
2个回答

10

你得到的错误信息是一个很正常的类型错误:addEventListener需要一个js.Function1[dom.Event, _],但是你给了一个js.Function1[dom.MouseEvent, _]。由于第一个参数处于逆变位置,这不符合类型检查。

有两种解决方案:要么使你的函数接受一个dom.Event,然后将其转换为dom.MouseEvent,像这样:

canvas.addEventListener("click", { (e0: dom.Event) =>
  val e = e0.asInstanceOf[dom.MouseEvent]
  ...
}, false)

或者您可以使用更精确的类型onclick

canvas.onclick = { (e: dom.MouseEvent) =>
  ...
}

是否有类似于 += 的运算符,例如 canvas.onclick += { (e: dom.MouseEvent) => ... } - David Portabella
1
@David Portarella:不,至少在默认的scalajs-dom外观中没有。也许存在某个库可以提供类似的功能。 - sjrd

1
事件捕获是指在事件目标的祖先上注册的EventListener可以在事件到达目标之前拦截给定类型的事件的过程。捕获从树的顶部(通常是文档)向下运行,使其成为冒泡的对称相反物,冒泡将在下面描述。在事件的初始分派之前,从树的顶部到事件目标的EventTargets链被确定。如果在事件处理期间对树进行修改,则事件流将基于树的初始状态继续进行。

http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-basic

window.addEventListener("click", function(){console.log('something1')}, false);
window.addEventListener("click", function(){console.log('something2')}, true);

订单将是

something 2(首先定义,使用capture=true)

something 1(第二次定义,使用capture=true)

Ref 2

关于第二个参考:顺序不保证!

捕获阶段

一种事件通过目标祖先之一处理后再由目标节点处理的过程。

REF 3


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接