{"id":122,"date":"2006-10-24T12:55:27","date_gmt":"2006-10-24T12:55:27","guid":{"rendered":"http:\/\/lachy.id.au\/log\/2006\/10\/xbl-part2"},"modified":"2006-12-14T00:02:05","modified_gmt":"2006-12-14T00:02:05","slug":"xbl-part2","status":"publish","type":"post","link":"https:\/\/lachy.id.au\/log\/2006\/10\/xbl-part2","title":{"rendered":"XBL Part 2: Event Handlers"},"content":{"rendered":"<p>This is part 2 in my 5 part series on <a href=\"http:\/\/www.w3.org\/TR\/xbl\/\">XML<br \/>\n    Binding Language<\/a>.  If you haven\u2019t already read <a href=\"\/log\/2006\/10\/xbl-part1\">part<br \/>\n    1<\/a>, I suggest you do so now before you continue reading. XBL provides<br \/>\n    a mechanism for attaching event listeners to elements, and declaring the<br \/>\n    conditions under which the handlers should be invoked. In this article, I&#8217;m<br \/>\n    going to compare traditional event handling techniques with those that will<br \/>\n    be provided using by XBL.<\/p>\n<h2 id=\"xbl-part2-tradevent\">Traditional Event Handling<\/h2>\n<p>The following example illustrates some typical <em>unobtrusive<\/em> scripting<br \/>\n  techniques to attach event listeners, including both the <code>window.onload<\/code> property<br \/>\n  and the <code>addEventListener()<\/code> function.<\/p>\n<pre><code>window.onload = function() {\r\n    var nav = document.getElementById(\"nav\");\r\n    var li = nav.getElementsByTagName(\"li\");\r\n    for (var i = 0; i &lt; li.length; i++) {\r\n        li[i].addEventListener(\"mouseover\", doSomething, false);\r\n    }\r\n}<\/code><\/pre>\n<p>Another common method, though generally considered bad practice these days,<br \/>\n  is to use the HTML <code>on<var>event<\/var><\/code> attributes, like the following.<\/p>\n<pre><code>&lt;li onmouseover=\"doSomething();\"&gt;...&lt;\/li&gt;<\/code><\/pre>\n<p>There are advantages and disadvantages to both methods, but the former is<br \/>\n  generally considered better because it separates the behaviour layer from the<br \/>\n  markup.  However, the latter is a simple declarative syntax that can be quite<br \/>\n  convenient in some cases.<\/p>\n<h2 id=\"xbl-part2-xblevents\">Handling Events with XBL <\/h2>\n<p>In XBL, instead of requiring authors to use a script to search for the elements,<br \/>\n  the event listeners are attached to those that the binding is attached to.<br \/>\n  XBL provides a simple declerative syntax which also continues to separate the<br \/>\n  behaviour layer from the semantic markup layer. Event listeners are declared<br \/>\n  using both the <a href=\"http:\/\/www.w3.org\/TR\/2006\/WD-xbl-20060907\/#the-handlers\"><code>handlers<\/code><\/a> element and its child <a href=\"http:\/\/www.w3.org\/TR\/2006\/WD-xbl-20060907\/#the-handler\"><code>handler<\/code><\/a> elements.<\/p>\n<p>In the previous article, we looked at how bindings are associated with elements<br \/>\n  using a selector, just like in CSS.  For example, this binding will be attached<br \/>\n  to all <code>li<\/code> elements within an element with <code>id=\"nav\"<\/code>.<\/p>\n<pre><code>&lt;xbl xmlns=\"http:\/\/www.w3.org\/ns\/xbl\"&gt;\r\n  &lt;binding element=\"#nav li\"&gt;\r\n    &lt;handlers&gt;\r\n      &lt;handler event=\"mouseover\"&gt;\r\n        doSomething();\r\n      &lt;\/handler&gt;\r\n    &lt;\/handlers&gt;\r\n  &lt;\/binding&gt;\r\n&lt;\/xbl&gt;<\/code><\/pre>\n<p>If present, only <em>one<\/em> <code>handlers<\/code> element is allowed within<br \/>\n  a binding, but it can contain as many child <code>handler<\/code> elements as<br \/>\n  required, to capture as many different events as you like. This binding declares<br \/>\n  a single event handler that listens for the <code>mouseover<\/code> event.<br \/>\n  When the <code>mouseover<\/code> event is fired on a bound element (i.e. an<br \/>\n  element to which this binding is attached), the handler is invoked in effectively<br \/>\n  the same way it would have been using the other methods shown above.<\/p>\n<h3 id=\"xbl-part2-eventfilters\">Event Filters<\/h3>\n<p>There are often times when you only want to handle an event under certain<br \/>\n  conditions.  For example, when you want to capture a <code>click<\/code> event<br \/>\n  and do something only when the user clicks the left mouse button; or capture<br \/>\n  a keyboard event and perform different functions depending on which key was<br \/>\n  pressed.  In traditional scripting techniques, you have to check the values<br \/>\n  of certain properties using <code>if<\/code> or <code>switch<\/code> statements<br \/>\n  in your function, like the following.<\/p>\n<pre><code>function doSomething(e) {\r\n    var code;\r\n    e = e || window.event;\r\n    code = e.keyCode || e.which;\r\n    switch(code) {\r\n        ...\r\n    }\r\n}<\/code><\/pre>\n<p>Much of that involves handling of browser incompatibilities, but even if all<br \/>\n  browsers supported the DOM Events standard, it\u2019s still quite complicated.<br \/>\n  XBL addresses this by providing a simple declarative syntax for describing<br \/>\n  these conditions using <a href=\"http:\/\/www.w3.org\/TR\/2006\/WD-xbl-20060907\/#attributes9\">attributes<br \/>\n  on the handler element<\/a>.<\/p>\n<p>In the following example, separate handlers are provided for for handling<br \/>\n  the <code>keypress<\/code> events depending on which character was entered.<br \/>\n  The first handles the character <kbd>a<\/kbd>, the second handles <kbd>b<\/kbd>.<br \/>\n  If any other character was entered, neither of these two handlers will be invoked.<\/p>\n<pre><code>&lt;handlers&gt;\r\n  &lt;handler event=\"keypress\" text=\"a\"&gt;\r\n    doSomethingA();\r\n  &lt;\/handler&gt;\r\n  &lt;handler event=\"keypress\" text=\"b\"&gt;\r\n    doSomethingB();\r\n  &lt;\/handler&gt;\r\n&lt;\/handlers&gt;<\/code><\/pre>\n<p>Similarly, in the following example, the handler will only be invoked when<br \/>\n  the user left clicks while holding the <kbd>Shift<\/kbd> key down.<\/p>\n<pre><code>&lt;handlers&gt;\r\n  &lt;handler event=\"click\" button=\"0\" modifiers=\"shift\"&gt;\r\n    doSomething();\r\n  &lt;\/handler&gt;\r\n&lt;\/handlers&gt;<\/code><\/pre>\n<h4 id=\"xbl-part2-commonfilters\">Other Common Event Filters<\/h4>\n<p>There are several other filters that can be used.  The following list is a<br \/>\n  subset of the available attributes for this purpose.  I suspect these will<br \/>\n  be the most commonly used filters because they cover the majority of mouse<br \/>\n  and keyboard event usage on the web today.<\/p>\n<dl>\n<dt><a href=\"http:\/\/www.w3.org\/TR\/2006\/WD-xbl-20060907\/#button\"><code>button<\/code><\/a><\/dt>\n<dd>A space separated list of mouse buttons pressed by the user. e.g. <code>button=\"0 2\"<\/code><br \/>\n      matches either the <strong>left<\/strong> <em>or<\/em> <strong>right<\/strong> mouse<br \/>\n      buttons.<\/dd>\n<dt><a href=\"http:\/\/www.w3.org\/TR\/2006\/WD-xbl-20060907\/#click-count\"><code>click-count<\/code><\/a><\/dt>\n<dd>The number of times the user clicked.  e.g. <code>click-count=\"2\"<\/code> matches <em>double<br \/>\n      clicks<\/em>.<\/dd>\n<dt><a href=\"http:\/\/www.w3.org\/TR\/2006\/WD-xbl-20060907\/#text\"><code>text<\/code><\/a><\/dt>\n<dd>The text entered by the user.  This is different from the key code because<br \/>\n    it matches the letter that was entered, regardless of the keys that were<br \/>\n    pressed.  This is particularly important for languages that require several<br \/>\n    key presses to enter certain letters.<\/dd>\n<dt><a href=\"http:\/\/www.w3.org\/TR\/2006\/WD-xbl-20060907\/#modifiers1\"><code>modifiers<\/code><\/a><\/dt>\n<dd>Modifer keys, including <kbd>alt<\/kbd>, <kbd>control<\/kbd>, <kbd>shift<\/kbd>, <kbd>meta<\/kbd>,<br \/>\n    etc.<\/dd>\n<dt><a href=\"http:\/\/www.w3.org\/TR\/2006\/WD-xbl-20060907\/#key\"><code>key<\/code><\/a><\/dt>\n<dd>Matches against the <a href=\"http:\/\/www.w3.org\/TR\/DOM-Level-3-Events\/keyset.html#KeySet-Set\">keyIdentifier<br \/>\n      value<\/a> defined in DOM 3 Events<\/dd>\n<dt><a href=\"http:\/\/www.w3.org\/TR\/2006\/WD-xbl-20060907\/#key-location\"><code>key-location<\/code><\/a><\/dt>\n<dd>For matching the location of the key that was pressed on the keyboard,<br \/>\n    including <code>standard<\/code>, <code>left<\/code>, <code>right<\/code> and <code>numpad<\/code>.<\/dd>\n<\/dl>\n<p>In the next article in this series, I\u2019ll be taking a look at XBL Templates, which will provide significant<br \/>\n   presentaional enhancements, particularly in regards to layout.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A comparison of traditional event handling and event handling with XBL.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,4,7],"tags":[],"_links":{"self":[{"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/posts\/122"}],"collection":[{"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/comments?post=122"}],"version-history":[{"count":0,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/posts\/122\/revisions"}],"wp:attachment":[{"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/media?parent=122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/categories?post=122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/tags?post=122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}