user3025403
user3025403

Reputation: 1080

Scala.js: Using addEventListener to add events to objects

In JavaScript, the addEventListener() method is used like this:

object.addEventListener("click", myScript);

In Scala.js: I have a canvas, and I want to listen to clicks only on the canvas, not the entire document. In the Scala.js.dom library, addEventListener is defined as:

 def addEventListener(`type`: String, listener: js.Function1[Event, _], useCapture: Boolean = ???): Unit = ???

I'm not sure what "useCapture" refers to. But I tried:

dom.document.getElementById("canvas").addEventListener("click", {
(e:dom.MouseEvent) => { /*do something*/ }
}, false)

And the error message I got:

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

Can someone explain what "useCapture" refers to, and how to correctly use addEventListener in Scala.js?

Upvotes: 7

Views: 4614

Answers (2)

sjrd
sjrd

Reputation: 22085

The error message you get is a perfectly normal type error: addEventListener expects a js.Function1[dom.Event, _], but you're giving it a js.Function1[dom.MouseEvent, _]. Since the first argument is in contravariant position, this does not typecheck.

There are two solutions: either you make your function take a dom.Event, that you then cast to dom.MouseEvent, like this:

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

or you use onclick which is more precisely typed:

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

Upvotes: 10

Pogrindis
Pogrindis

Reputation: 8091

Event capture is the process by which an EventListener registered on an ancestor of the event's target can intercept events of a given type before they are received by the event's target. Capture operates from the top of the tree, generally the Document, downward, making it the symmetrical opposite of bubbling which is described below. The chain of EventTargets from the top of the tree to the event's target is determined before the initial dispatch of the event. If modifications occur to the tree during event processing, event flow will proceed based on the initial state of the tree..

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);

The order will be

something 2 (defined first, using capture=true)

something 1 (defined second using capture=true)

Ref 2

Note on the second ref: The order is not guaranteed!

capture phase

The process by which an event can be handled by one of the target ancestors before being handled by the target node.

REF 3

Upvotes: 1

Related Questions