The DOM Level 2 Event Model is designed with two main goals. The first goal is the design of a generic event system which allows registration of event handlers, describes event flow through a tree structure, and provides basic contextual information for each event. Additionally, the specification will attempt to provide standard sets of events for user interface control and document mutation notifications, including defined contextual information for each of these event sets.
The second goal of the event model is to provide a common subset of the current event systems used within Microsoft Internet Explorer 4.0 and Netscape Navigator 4.0. This is intended to foster interoperability of existing scripts and content. It is not expected that this goal will be met with full backwards compatibility. However, the specification attempts to achieve this when possible.
The following constitutes the list of requirements for the DOM Level 2 Event Model.
Requirements of event flow:
Node
.Requirements of event listener registration:
Requirements of contextual event information:
Requirements of event types:
Event flow is the process through which the an event originates from the DOM implementation
and is passed into the Document Object Model. The methods of event capture and event
bubbling, along with various event listener registration techniques, allow the event
to then be handled in a number of ways. It can be handled locally at the target
Node
level or centrally from a Node
higher in the document tree.
Each event has a Node
toward which the event is directed by the DOM implementation. This
Node
is the event target. When the event reaches the target, any event
listeners registered on the Node
are triggered. Although all EventListener
s
on the Node
are guaranteed to receive the event, no specification is made as to the order
in which they will receive the event with regards to the other EventListener
s on the
Node
. If neither event
capture or event bubbling are in use for that particular event,
the event flow process will complete after all listeners have been triggered. If event capture
or event bubbling is in use, the event flow will be modified as described in the sections below.
Event capture is the process by which an ancestor of the event's target can register to intercept events of a given type before they are received by the event's target. Capture operates from the top of the tree downward, making it the symmetrical opposite of bubbling which is described below.
An EventListener
being registered on an EventTarget
may choose to have that EventListener
capture events by
specifying the useCapture
parameter of the addEventListener
method to be true. Thereafter, when an event of the given type is
dispatched toward a descendant of the capturing object, the event
will trigger any capturing event listeners of the appropriate type
which exist in the direct line between the top of the document and the
event's target. This downward propagation continues until either no additional
capturing EventListener
s are found or the event's target is
reached.
If the capturing EventListener
wishes to prevent further
processing of the event it may set the cancelCapture
property of the Event
to true. This will prevent further dispatch of the event to additional
EventTarget
s lower in the tree structure, although additional EventListener
s registered at
the same hierarchy level will still receive the event. However, if after dispatching
the event to the final EventListener
at a
given level, the value of cancelCapture
is false, the implementation
then propagates the event down to the next capturing EventListener
existing between itself and the event's target. If no additional capturers exist,
the event triggers the appropriate EventListener
s on the target
itself.
Although event capture is similar to the delegation based event
model, it is different in two important respects. First, event capture
only allows interception of events which are targeted at descendants
of the capturing Node
. It does not allow interception of events
targeted to the capturer's ancestors, its siblings, or its
sibling's descendants. Secondly, event capture is not specified for
a single Node
, it is specified for a specific type of event.
Once specified, event capture intercepts all events
of the specified type targeted toward any of the capturer's descendants.
Events which are designated as bubbling will initially proceed with the
same event flow as non-bubbling events. The event is dispatched to their target
Node
and any event listeners found there are triggered. Bubbling
events then perform a check of the event's cancelBubble
attribute. If the
attribute is false, the event will then look for additional event listeners by following the
Node
's parent chain upward, checking for any event listeners
registered on each successive Node
. This upward propagation will continue
all the way up to the Document
unless either the bubbling process is
prevented through use of the cancelBubble
attribute.
An event handler may choose to prevent continuation of the bubbling process at any
time through use of the cancelBubble
attribute on the event object. After
dispatching the event to all EventListener
s on a given EventTarget
the value of the cancelBubble
property is checked. If the value is true, bubbling
will cease at that level. If the value is false, bubbling will continue upward to the parent
of the current EventTarget
.
Some events are specified as cancellable. For these events, the
DOM implementation generally has a default action associated with the
event. Before processing these events, the implementation must check for
event listeners registered to receive the event and dispatch the event to
those listeners. These listeners then have the option of cancelling the
implementation's default action or allowing the default action to proceed.
Cancellation is accomplished by setting the event's
returnValue
attribute to false.
The EventSource
interface is implemented by Node
s which
can be targetted by events. The interface allows event listeners to be registered on
the node.
interface EventTarget { void addEventListener(in DOMString type, in boolean postProcess, in boolean useCapture, in EventListener listener); void removeEventListener(in DOMString type, in boolean postProcess, in boolean useCapture, in EventListener listener); };
addEventListener
type |
The event type for which the user is registering | |
postProcess |
If true, (ED:
Should an invalid postProcess value raise an exception?
)
| |
useCapture |
If true, | |
listener |
The |
removeEventListener
EventListener
is removed from an EventTarget
while it is
processing an event, it will complete its current actions but will not be triggered
again during any later stages of event flow.
type |
Specifies the event type of the | |
postProcess |
Specifies whether the | |
useCapture |
Specifies whether the | |
listener |
The |
The EventListener
interface is the primary method for handling events. Users
implement the EventListener
interface and register their listener on a
EventTarget
using the AddEventListener
method.
interface EventListener { void handleEvent(in Event event); };
handleEvent
EventListener
interface was registered.
event |
The |
In HTML 4.0, event listeners where specified as properties of an element. As such,
registration of a second event listeners of the same type would override the value of the
first listener. The DOM Event Model allows registration of multiple event listeners on
a single Node
. To achieve this, event listeners are no longer stored as property
values.
In order to achieve compatibility with HTML 4.0, implementors may view the setting of
properties which represent event handlers as the creation and registration of an
EventListener
on the Node
. The value for postProcess
should
be given a default value appropriate for the event. This EventListener
behaves in
the same manner as any other EventListeners
s which may be registered on the
Node
. If the property representing the event listener is changed, this may be
viewed as the removal of the previously registered EventListener
and the
registration of a new one.
The first issue is a question of whether listeners should exist as typed interfaces containing groups of similar events or instead as a single generic listener. An example of the first case would be:
interface MouseListener : EventListener{ MouseDown(); MouseUp(); Click(); }
whereas the second is:
interface EventListener { HandleEvent(); }
The specification currently defines listeners via the second solution. This solution avails itself more readily to extending or creating new events. The first solution would require defintion of new event interfaces in order to add events. However, remaining problems with the first solution include the fact that registering the same object for multiple events requires the user to differentiate between the events inside the event listener. The current string based event typing system could make this very inefficient. The DOM Working Group is exploring alternatives to the string based event typing to resolve this issue.
The second issue concerns event ordering. If multiple event handlers are registered on
the same node ordering may need to be imposed on the event delivery. One solution to
this includes adding an ordering scheme into the listener registration mechanism. This would
also necessitate adding a method for introspection of registered listeners to EventTarget
. A second solution imposes ordering through registration order. However, this
breaks down quickly if multithreading is allowed. A third solution is to specify that event
ordering is left to the application.
Lastly, a full solution has not yet been added to meet the suggestion that all listeners
be notified of the final resolution of an event. It is possible that use of both pre- and
post-processing of events will achieve this goal but it is not yet clear if this solution
will be sufficient.
The Event
interface is used to provide contextual information about an event
to the handler processing the event. An object which implements the Event
interface
is generally passed as the first parameter to an event handler. More specific
context information is passed to event handlers by deriving additional interfaces from
Event
which contain information directly relating to the type of event
they accompany. These derived interfaces are also implemented by the object passed to the
event listener.
interface Event { attribute DOMString type; attribute Node target; attribute Node currentNode; attribute boolean cancelBubble; attribute boolean cancelCapture; attribute boolean returnValue; };
type
type
property represents the event name as a string property.
target
target
property indicates the Node
to which the event
was originally dispatched.
currentNode
currentNode
property indicates to which Node
the event
is currently being dispatched. This is particularly useful during capturing and bubbling.
cancelBubble
cancelBubble
property is used to control the bubbling phase of
event flow. If the property is set to true, the event will cease bubbling at
the current level. If the property is set to false, the event will bubble up to its parent.
The default value of this property is determined by the event type.
cancelCapture
cancelCapture
property is used to control propagation during the
capturing phase of event flow. If the property is set to true, the event will not
propagate down any further in the tree. If the property is set to false, the event
will continue down to the next capturing node, or if none exists, to the event target.
The default value of this property is false.
returnValue
returnValue
property is checked by the DOM implementation
after the event has been processed by its event handlers. If the returnValue
is false, the
DOM implementation does not execute any default actions associated with the event.
The UIEvent
interface provides specific contextual
information associated with User Interface and Logical events.
interface UIEvent : Event { attribute long screenX; attribute long screenY; attribute long clientX; attribute long clientY; attribute boolean altKey; attribute boolean ctrlKey; attribute boolean shiftKey; attribute unsigned long keyCode; attribute unsigned long charCode; attribute unsigned short button; };
screenX
screenX
indicates the horizontal coordinate at which the event occurred in
relative to the origin of the screen coordinate system.
screenY
screenY
indicates the vertical coordinate at which the event occurred
relative to the origin of the screen coordinate system.
clientX
clientX
indicates the horizontal coordinate at which the event occurred
relative to the DOM implementation's client area.
clientY
clientY
indicates the vertical coordinate at which the event occurred
relative to the DOM implementation's client area.
altKey
altKey
indicates whether the 'alt' key was depressed during the firing
of the event.
ctrlKey
ctrlKey
indicates whether the 'ctrl' key was depressed during the firing
of the event.
shiftKey
shiftKey
indicates whether the 'shift' key was depressed during the firing
of the event.
keyCode
keyCode
holds the virtual key code value of the key which was
depressed if the event is a key event. Otherwise, the value is zero.
charCode
charCode
holds the value of the Unicode character associated with the depressed
key if the event is a key event. Otherwise, the value is zero.
button
button
is used to indicate which mouse button changed state.
The MutationEvent
interface provides specific contextual
information associated with Mutation events.
interface MutationEvent : Event { attribute Node relatedNode; attribute DOMString prevValue; attribute DOMString newValue; attribute DOMString attrName; };
relatedNode
relatedNode
is used to identify a secondary node related to a mutation event.
For example, if a mutation event is dispatched to a node indicating that its parent
has changed, the relatedNode
is the changed parent. If an event is instead
dispatch to a subtree indicating a node was changed within it, the relatedNode
is the changed node.
prevValue
prevValue
indicates the previous value of text nodes and attributes in
attrModified and charDataModified events.
newValue
newValue
indicates the new value of text nodes and attributes in
attrModified and charDataModified events.
attrName
attrName
indicates the changed attr in the attrModified event.
The main issue with respect to the Event
object
regards how this object will be made accessible to the EventListener
. The specification current passes the Event
as the first parameter
of the handleEvent
method. However, some compatibility concerns have been
raised with this approach. Alternatives to this method are being explored.
A secondary issue exists regarding the possible addition of a new property to the base
Event
interface to indicate to which Node
the event is currently
being dispatched. This would alleviate possible confusion during the bubbling and
capturing phases when the same EventListener
is registered upon multiple
nodes. The property has been added while its necessity is under discussion.
The DOM Level 2 Event Model allows a DOM implementation to support multiple sets of events. The model has been designed to allow addition of new event sets as is required. The DOM will not attempt to define all possible events. For purposes of interoperability, the DOM will define a set of user interface events, a set of UI logical events, and a set of document mutation events.
The User Interface event set is composed of events listed in HTML 4.0 and additional events which are supported in both Netscape Navigator 4.0 and Microsoft Internet Explorer 4.0.
User Inteface event issues: Different implementations receive user interface events in different orders or don't receive all events specified. For example, in some implemenations a dblclick event might occur as the user presses the mouse button down, in others it may occur as the user releases the mouse button. There are two possible solutions to this. The first is that the DOM Level 2 Events specification my define the user interface events that will be delivered and the order in which they will be delivered. Implementations would then deliver the events specified, making translations as necessary from the events being delivered to the implementation. The other solution is to define User Interface events as varying from implementation to implemenation, making no guarantee on the ordering of event delivery.
The mutation event set is designed to allow notification of any changes to the structure of a document, including attr and text modifications. It may be noted that none of the mutation events listed are designated as cancellable. The reasoning for this stems from the fact that it would be very difficult to make use of existing DOM interfaces which cause document modifications if any change to the document might or might not take place due to cancellation of the related event. Although this is still a desired capability, it was decided that it would be better left until the addition of transactions into the DOM.
It should also be noted that many of the mutation events have been designed in
pairs, one which bubbles and one which does not. An example of this is the pair of
events childInsertedOntoParent and nodeInsertedOntoParent. The first event,
childInsertedOntoParent, is dispatched to the prospective parent node and bubbled
up through the document. The second event is dispatched to the child node and
does not bubble. The intention is that both the child and parent will be able to
receive the desired notifications whether registered as pre-processing or post-processing
EventListener
s. For example, when an EventListener
is
registered for pre-processing of this event, the child Node
is not yet
attached to its new parent and bubbling is insufficient to allow notification of the
imminent structural change to both the child and parent. Thus, pairs of events
are necessary to describe all possible document changes. One of each pair of these
events is designated as non-bubbling to prevent overlapping notifications when
handling the post-processing listener case.
attr
is modified on a node. The target of
this event is the node whose attr
changed.CharacterData
within a node is modified but the node
itself has not been inserted or deleted. The target of this event
is the CharacterData
node.The HTML event set is composed of events listed in HTML 4.0 and additional events which are supported in both Netscape Navigator 4.0 and Microsoft Internet Explorer 4.0.