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 EventListeners
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 EventListeners 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 EventListeners 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
EventTargets lower in the tree structure, although additional EventListeners 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 EventListeners 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 EventListeners 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 Nodes 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);
};
addEventListenertype |
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 |
removeEventListenerEventListener 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 EventListenerss 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;
};
typetype property represents the event name as a string property.
targettarget property indicates the Node to which the event
was originally dispatched.
currentNodecurrentNode property indicates to which Node the event
is currently being dispatched. This is particularly useful during capturing and bubbling.
cancelBubblecancelBubble 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.
cancelCapturecancelCapture 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.
returnValuereturnValue 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;
};
screenXscreenX indicates the horizontal coordinate at which the event occurred in
relative to the origin of the screen coordinate system.
screenYscreenY indicates the vertical coordinate at which the event occurred
relative to the origin of the screen coordinate system.
clientXclientX indicates the horizontal coordinate at which the event occurred
relative to the DOM implementation's client area.
clientYclientY indicates the vertical coordinate at which the event occurred
relative to the DOM implementation's client area.
altKeyaltKey indicates whether the 'alt' key was depressed during the firing
of the event.
ctrlKeyctrlKey indicates whether the 'ctrl' key was depressed during the firing
of the event.
shiftKeyshiftKey indicates whether the 'shift' key was depressed during the firing
of the event.
keyCodekeyCode holds the virtual key code value of the key which was
depressed if the event is a key event. Otherwise, the value is zero.
charCodecharCode holds the value of the Unicode character associated with the depressed
key if the event is a key event. Otherwise, the value is zero.
buttonbutton
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;
};
relatedNoderelatedNode 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.
prevValueprevValue indicates the previous value of text nodes and attributes in
attrModified and charDataModified events.
newValuenewValue indicates the new value of text nodes and attributes in
attrModified and charDataModified events.
attrNameattrName 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
EventListeners. 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.