The World Wide Web Consortium (W3C) HTML event model provides a way to respond to user actions. In the model, which is part of the HTML DOM, user actions can be associated with a DOM element. When an action occurs on the DOM element, the browser generates an event and invokes the JavaScript code subscribed to the element, for a particular event type. The W3C HTML event model defines standard event types, such as load, mouseover, click, and resize, corresponding to user actions.
The framework implements an event model very similar to the W3C HTML event model. One difference is that the framework defines event types at a higher level of abstraction, representing actions meaningful to the UI model and framework widgets.
Mojo defines unique event types supporting different parts of the UI system:
You should refer to the API documentation, specifically Mojo.Event, for a complete list with descriptions and references to the event object properties and related information. For the System and Application UI event types, the meaning of the event depends on the context in which the event occurs, and you need to handle the event accordingly.
The framework also provides a way to define custom events and
propagate events to an event handler through Mojo.Event.make
and
Mojo.Event.send
.
When an event occurs, all code that is subscribed to handle the event is notified. You can subscribe to events on any DOM element by calling one of the following methods:
Mojo.Event.listen()
or
this.controller.listen()
<DOM Element
ID>.addEventListener()
observe()
These methods are roughly equivalent, differing only in call
semantics. Mojo.Event.listen
was created
as a contingency for issues with either addEventListener
or
Prototype’s observe
method, but at
this point, all work equally well with Mojo.
There is an issue with referencing elements by DOM ID. The Prototype $
and getElementById
won’t work
across Stage boundaries, so if you have a multistage application, you
will need to use this.controller.listen()
if you pass an
element by DOM ID, or this.controller.get()
when
you want to retrieve an element by DOM ID.
As in the standard HTML model, events bubble up the DOM tree and the parent DOM element receives the events that occur on any child elements. For controls, this implies that you should observe events on the enclosing div element instead of on an element that is part of the control implementation.
The following code snippets show how to subscribe to events using
this.controller.listen
:
Define the HTML DOM element associated with an event and assign an ID to the element:
<div id="thanksButton">Thank you</div>
Provide a JavaScript method to handle the event:
MySceneAssistant.prototype.handleThanks = function() { this.sceneAssistant.outputDisplay.innerHTML = "Thanks";}
This is the handler specified when the user subscribes to the event. The method is invoked by the browser when the event occurs. You should provide the event handling logic appropriate for the event and application context.
Subscribe to the event, using the element ID and specifying the event handler method:
this.controller.listen("thanksButton", Mojo.Event.tap, this.handleThanks.bindAsEventListener(this));
You will typically need to use bind
or bindAsEventListener
on your event listeners. The JavaScript this
keyword will be set to either the window or the DOM element when your
event listener is called. You will want to use bind
or bindAsEventListener
to make sure that the
this keyword will point to the same scene
assistant instance that registered the handler.
Use one of the following methods to remove your listener from events:
Mojo.Event.stopListening()
or this.controller.stopListening()
<DOM Element
ID>.removeEventListener()
stopObserving()
You should use the method that corresponds to the method used to set up listening for the event; in other words, use the same Mojo method to stop listening that you used to initiate listening.
With any of these methods, you must use the exact handler
reference used in the listen method call. In the above example, the
handler was specified as this.handleThanks.bindAsEventListener(this)
,
which won’t work in the stopListening
method. Try this instead:
this.eventHandler = this.handleThanks.bindAsEventListener(this); this.controller.listen("thanksButton", Mojo.Event.tap, this.eventHandler); . . . this.controller.stopListening("thanksButton", Mojo.Event.tap, this.eventHandler);
Note that if you include the useCapture
argument when setting up your
listener, you must also include it with the stopListening
call in exactly the same
way.
There are two ways to leak memory in JavaScript. The
first is to have a circular reference between the closure of an event
handler and the node that you call addEventListener
on. Since the event won’t
be unregistered until the node is destroyed, and the node won’t be
destroyed until the JavaScript reference goes away, it causes a memory
leak.
The second form of leaking is more straightforward, which is to
have a persistent reference to a closure (like setInterval
or a Mojo service subscription)
that has a direct or indirect reference to a DOM node. Those objects
and nodes will also live forever.
Many widgets dispatch events. Applications can use these to better leverage the
functionality built into the controls. Events are generally dispatched
to the widget’s element, the div defined in the scene’s view HTML that
has the x-mojo-element
attribute.
Appendix B enumerates all the
specific events propagated by each widget in options tables accompanying
each widget’s description.
3.145.107.1