| Unobtrusive Event Handling with Prototype |
|
|
|
Event Handler TypesThere are two main types of event handlers in JavaScript, DOM level 0 and DOM level 2. DOM level 0 is the type of event handling that we all learned when we first were exposed to JavaScript: <a href="javascript:void(0);" onclick="alert('Hello, world!');" id="clickMeLink">or <html> So what is wrong with that? It has always worked in the past, right? There are two issues with the above: coupling and event overriding. Coupling and Event OverridingWe all know coupling is bad. We decouple our data access from our views, we decouple our services from eachother, we try to keep coupling to a minimum in every piece of code we right...except our JavaScript. Coupling of our JavaScript to markup prevents you from changing your markup without addressing your JavaScript as well. For example, let's say we didn't want to have the Click Me be a link anymore. Let's say we wanted it to be cell on a table. How would you do that? You would change the markup, but then you would have to change the JavaScript as well. If you were using unobtrusive JavaScript, all you would have to do is change the markup. The JavaScript would still reference the same id so nothing would have to change. Event overriding is the second reason to avoid the above way of doing JavaScript. What do I mean by event overriding? The way the event handlers in the previous example are associated are with what is called DOM Level 0 events. The issue with DOM Level 0 events is that you can only assign one event handler to a DOM Level 0. With unobtrusive JavaScript (using Prototype), you actually assign event handlers to a higher level (DOM Level 2 to be exact). This level allows for multiple event handlers to be assigned to one event. For example <html> The alert "I beat you" would be displayed, but the "Hello, world!" would not. If you used unobtrusive JavaScript, both could be triggered. Enter PrototypeSo to ileviate the issues talked about before, we would rather use Prototype and develop unobtrusive JavaScript. At the core of Prototype's event handling is the Event.observe method. This method is used to associate an event handler with an element and it's related event. So to recreate the above hello world example, we would do the following: <html> To associate a handler to an event we call Event.observe with three parameters: an element (window in this case), the event to trigger the handler (in this case load), and finally a function to be called. In this case we defined the function inline, however you can define the handler elsewhere as well. Now let's take a look at the second scenario we presented earlier. The one where the onload in the body tag would override the window.onload assignment in the JavaScript. <html> In the redone version above, both alert boxes will fire once the page loads instead of whoever was loaded last like in the orgional version. Finally, let's look at the click here example. Below, we have the origional link but now the JavaScript is associated with the id. So if we want to change the markup, all we need to do is associate the same id to the new element and the JavaScript will still work (fyi, $() is Prototype shorthand for document.getElementById()). <script> So that's all there is to it. I hope this helps you take a step towards better JavaScript writing. Good luck! 10 ResponsesAdd your own comment... |
| < Prev |
|---|
Thank you so much for the tutorial.
However, in trying out the very last simple example I get an "element has no properties" error. Do you know what the issue may be?
The last example will not work because the script will not find the element when the page is loading. That can be solved by putting the script after the div element. Otherwise you can do something like this --
Event.observe(
window,
'load',
function()
{
Event.observe('link1','click',function(){alert("A simple click");});
}
);
In my last comment the id of the link should be 'clickMeLink' and not 'link1'
Abhijit,
Good catch! Unfortunately, depending on where your example is put, even the load event may not suffice. To truly be safe, you should use one of the DOMReady plugins available on the net. That way the DOM has been constructed and you know that the object you are referencing will exist.
Thanks,
Michael
in your example of the clickme link. what if you want to pass something front that link to the javascript? the old way i would do
Click Me
how can i pass those when i use event.observe?
AFAIK DOMReady comes before window.load. DOMReady can since Prototype 1.6 be observed with document.observe('dom:loaded', function() {...})
@parissa: Check out bind() and bindAsEventListener()
http://prototypejs.org/api/function
Use it like
Event.observe('link1','click',alert.bind("A simple click"));
Made a typo, substitute curry() for bind() in the last example.
how to do this without the id