Steven Pemberton, W3C/CWI
Version date: 21 July 2004
This document is a quick introduction to XML Events for HTML authors. XML
Events is a method of catching events in markup languages that offers several
advantages over the HTML onclick
style of event handling.
The important thing to know about XML Events is that it uses exactly the same event mechanism as HTML, only written differently.
Consider this simple HTML example:
<input type="submit" onclick="verify(); return true;">
This says that if the <input>
element (or any of its
children) gets the click
event, then the piece of code in the
onclick
attribute is performed.
We say "or any of its children" because in a case like
<a href="..." onclick="...">A <em>very</em> nice place to go</a>
or
<a href="..." onclick="..."><strong>More</strong></a>
you want the onclick
to be performed even if the click
actually happens on the <em>
or
<strong>
elements. In these cases we call the element that
was clicked on the target, and the element that responds to the
event an observer (though often target and observer are the same
element).
So what you see is that there are three important things involved: an event, an observer, and a piece of script (called a handler). As you can see from the above, the fourth thing, the target, isn't usually important.
There are some problems with the way HTML specifies the relationship between the three:
onflash
if an event called
flash
were introduced.click
, when in fact you don't care how the button
is activated, only that is has been activatedonclick
, one for JavaScript and one for
VB)XML Events specifies the relationship between the event, observer and handler in a different way. The equivalent to:
<input type="submit" onclick="validate(); return true;">
would be:
<input type="submit"> <script ev:event="DOMActivate" type="text/javascript"> validate(); </script> </input>
(Note that there is no markup language yet that allows you to write exactly this: these examples just show what the equivalent markup would be, in order to explain the concepts. There are some pointers at the end to languages that already use XML Events.)
This says that the <script>
element is a handler for
the DOMActivate
event (which we use in preference to
click
, because buttons can be activated in different ways, not
just by clicks), and in the absence of any other information, the parent
element is the observer (<input>
in this case).
(Note that handlers must only be evaluated when the event happens, and not
when the document is loading as with <script>
in
HTML4.)
This approach now allows you to specify handlers for different scripting languages:
<input type="submit"> <script ev:event="DOMActivate" type="text/javascript"> ... </script> <script ev:event="DOMActivate" type="text/vbs"> ... </script> </input>
and/or different events:
<input type="submit"> <script ev:event="DOMActivate" type="text/javascript"> ... </script> <script ev:event="DOMFocusIn" type="text/javascript"> ... </script> </input>
You now know enough to be able to do event handling using XML Events. However, there are some other useful features.
Just as with HTML, there are other ways you can specify the
event-observer-handler relationship. You can put the information on the
handler, on the observer, or on a <listener>
element. Note
that whichever method you use, you always have to specify the three parts: so
if you use the handler you have to say what the event and observer are, if
you use the observer you have to say what the event and handler are, and with
<listener>
you have to specify all three.
The reason why you would want to this is mostly to make your documents more manageable. You can separate all scripting out of the main body of your document. It also allows you to avoid duplicating your handlers, and just having one copy which you can apply to several places.
Here you move the handler to some other part of the document, and specify
the relationship there (like some versions of HTML use the for
attribute on the <script>
element):
<script ev:observer="button" ev:event="DOMActivate" type="text/javascript"> validate(); </script> ... <input type="submit" id="button"/>
Here you again put the handler somewhere, and specify the relationship in
another place with the <listener>
element (this allows you
to use the same handler for more than one observer):
<ev:listener observer="button" handler="#validator" event="DOMActivate"/> ... <script id="validator" type="text/javascript"> validate(); </script> ... <input type="submit" id="button"/>
(Note that in this case it is the <listener>
element
that carries the ev:
prefix, and not the attributes.)
And finally, you can specify the relationship on the observer:
<script id="validator" type="text/javascript"> validate(); </script> ... <input type="submit" ev:handler="#validator" ev:event="DOMActivate"/>
Really for everyday use of events, that's all you need to know. There are however a few details that may occasionally come in useful.
Since, as was said, event handlers get invoked for an element or any of its children, it is possible for instance to listen for all clicks on anything within a paragraph:
<p> <script ev:event="DOMActivate" type="..."> ... </script> ... <a href="...">...</a> ... <a href="...">...</a> ... </p>
which would respond to clicks on either contained <a>
(as well as on anything else in the paragraph).
However, since the <a>
elements might also have
handlers on them, the phase
attribute is used to specify whether
a given handler should be activated before handlers lower in the tree, or
after them. Normally handlers lower in the tree for an event are activated
first, but the attribute ev:phase="capture"
causes a handler
higher in the tree to be executed before lower handlers for the same
event:
<p> <script ev:event="DOMActivate" ev:phase="capture" type="..."> <!-- This handler will be done before any lower in the tree --> ... </script> ... <a href="...">...</a> ... <a href="...">...</a> ... </p>
If you really do care about which element is the target, then you can say that you are only listening for events for that element:
<p> <script ev:event="DOMActivate" ev:target="img1" type="..."> ... </script> ... <a href="..."><img id="img1" ... /><img id="img2" ... /></a> </p>
(Remember, the target is the thing actually clicked on, which we usually aren't particularly interested in.)
Event handlers for an event are handled in the following order: first all
handlers with ev:phase="capture"
, starting first at the top of
the tree, and then working down to the target's parent element, and then all
other handlers, working from the target element, back up to the top of the
tree.
If any handler has ev:propagate="stop"
then no handler after
those on the current element will be invoked for the current event.
<body> <script ev:event="DOMActivate" ev:propagate="stop" ev:phase="capture" type="..."> <!-- This script is the only one that will respond to DOMActivate --> ... </script> ... </body>
By the way, if there is more than one handler on an element for the same event, it is undefined what order they are performed in.
Many events have a default action which gets carried out after
all event handlers for the event in the tree have been performed. For
instance, a click on a button will cause the button to be activated, a click
on an <a>
or one of its children will cause the link to be
activated. It is possible to stop this default action with the attribute
ev:defaultAction="cancel"
.
<input type="submit" ...> <script ev:event="DOMActivate" ev:defaultAction="cancel" type="..."> <!-- This script will be activated, but the default action will not be done --> ... </script> </input>
(This is what onclick="...; return=false;"
does in HTML4. If
you want to do this conditionally in XML Events, you should call the DOM
preventDefault
method appropriately.)
This introduction has shown you how to do event handling in XML. As mentioned above, presently there is no version of XHTML that supports XML Events with scripting; XHTML2 is in preparation. XForms uses XML Events (though with its own <action> element rather than <script>); other languages that use XML Events are XHTML+Voice (also known as X+V), and SVG 1.2 (also in preparation).
Copyright ©2004 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply. Your interactions with this site are in accordance with our public and Member privacy statements.