Tag Archives: events

EventSound, round 3

And here we are, the penultimate version of EventSound has been uploaded. And the only feature that is missing for 1.0 is… the sound. It looks like I’ll have to find samples on the Internet now.

I’m rather happy with the development pace of this application. It all started last Saturday and in four days we have something up and running, nice looking and maybe even useful! Altogether the application consists of one static HTML page and two scripts for a total of approx. 350 nice lines of JavaScript/jQuery.

I learned a lot writing this experiment, event delegation with jQuery is not only easy and powerful, but it feels natural. At some point you’ve got the impression to write XBL with this feature. For example there is one event listener for each kind of snippet (one by tab basically). But all of those are listening to the “update” event that can be triggered in three ways:

  • when the content of an input is modified (either by clicking on the scene or typing text)
  • when commented code is clicked
  • when removing the snippet

And then we just do event delegation:

  • once to detect the modification of an input value and triggers the update event for the parent snippet,
  • once to detect the click on commented code and trigger the update event on the parent snippet and modify the color of the code,
  • once to detect the click on the “-” to trigger the update event on the parent snippet and remove it,
  • once to detect the click on the “+” to duplicate the snippet.

And that’s basically it. Create a new tab, add a div with a class “.snippet” in it, then insert an input, a div with a class “.comment”, a link with a class “.remove”, a link with a class “.add” and all those features will work right away. The only thing left to implement is what happens when the snippet is updated. It’s like having behaviours attached to some kind of elements and you compose another element with those building blocks, you give it a specific behaviour and you can in turn duplicate this bigger building block.

Event delegation could be seen as a great advantage for the Open Web as a development platform. Which other technology offers this mechanism out of the box? Although it can be achieved with ActionScript or other technologies, it implies to rethink and reimplement strategies to broadcast events to higher levels… you end up reinventing the DOM!

Just as for the first round of EventSound, I let you find what the last two tabs are for. It should be fairly easy to figure it out.

EventSound, round2

The second iteration of EventSound has been uploaded. It doesn’t make any sound yet (I’m waiting for samples from my brother and my friend Lorenzo) but there are new nice improvements since last time.

EventSound is an application aimed at explaining how events work in the DOM and how to write code relying on events with jQuery. Not only is the interface built with jQuery and jQuery-ui, but the interface itself consists of snippets of JavaScript/jQuery code that can be used to play sounds when events occur on the scene (the left panel). You need to be familiar with the basics of the jQuery syntax to understand those snippets. Fortunately I wrote a quick introduction to jQuery for my final report (see “Dealing with the DOM”).

Illustration of event propagation

You will immediately notice that the bubbling of the events is decomposed on the scene. If you click on an element, you will see the click event being triggered on the element and then all of its ancestors.

Simple listeners

The first thing you can do with the application is to bind event listeners to scene’s elements using the snippets in the bind tab. The only thing you have to do is to fill the space reserved for the CSS selector in a snippet. To do so, there are two possibilities:

  • You look at the source of the scene to search for the classes and ids of its elements. There is no need to use ctrl+U or Firebug for that since I’ve implemented a neo mode: as long as you hold down the control key, you can see the Matrix! Be careful, you cannot dodge bullets.
  • You click in the space reserved for the selector and then click on any element on the scene. Simple, isn’t it?

The neo mode has been implemented just for fun. I read an interesting article by Atul Varma recently about Kids and the Open Web, and I tried to imagine a cool way to introduce non-programmers to the source of a Web page. I came up with this Matrix analogy: the ability to see (and later modify) what makes the Web we live in. Unfortunately it won’t take long before we see a generation of kids who don’t know about the World imagined by the brothers Wachowski.

From here, when you click on an element of the scene, as the bubbling event reaches an element that has a listener attached, the opacity of the listener changes. This is where the “Sound” of “EventSound” should make sense, because you will hear something, in the future, once the samples are ready (guys, if you’re reading me…).

Using those snippets it is also possible to cancel the bubbling of the events in the jQuery way: by returning false. Simply click on the last commented line of code… and pray for this feature to work ; )

Cloning elements and listeners

The second thing you can do in the application is to clone elements of the scene. You need to uncomment the single line of code in the snippet of the “instructions” tab. The next time you will click on an element it will be cloned and inserted gently, as the code suggest: the position and the color of the element is modified and appropriate id and class are set. Don’t take my word on that, enter the Matrix!

There are two comments in a single line of code (resulting in a CSS nightmare), the second one is a true parameter for the clone method which also clones the event listeners. When uncommented, if an event listeners is bound to an element and you clone this element, when a bubbling event reaches the clone, the event will also fire (unless there is a bug in the application, hehe).

Live events

.live() is a function introduced in jQuery 1.3 which brings event delegation to the masses: using this function, instead of binding events to individual elements (and having to clone the listeners when you add an element later), you bind a listener on a higher level and use the bubbling property of events to listen to the events occurring on a lower level.

This time you need to select both the elements on which you want to detect the event, and the higher element that you will use to bind the listener. For that I’m using a special syntax of jQuery where I do not pass only a CSS selector to jQuery, but also a context. Be careful, this syntax only works for event delegation with the upcoming jQuery 1.3.3.

[code lang="js"]
$("<selector>", $("<context>")[0])...
[/code]

Currently, to be successfully set, the context needs to be a DOM element, not a CSS selector, not a jQuery object, simply a DOM element, hence the [0] at the end of my jQuery object. I proposed a patch to be able to get rid of this [0] and thus reduce the number of function calls but it hasn’t been accepted yet.

You can now clone and add elements inside your context without worrying of attaching new listeners, great! And soon or later I hope that my bigger patch will eventually be accepted in jQuery so that you don’t have to worry about performances of event delegation.

And now…

I need your comments as I’m going to reuse this Blog post for my presentation on Saturday. What could be clarified? What could be improved? What did I do wrong? What is good, if any?

In the meantime I’ll work on the last two tabs and start to create my slides.