Early event handlers

  • This page describes Version 2 techniques. They don’t work in Explorer 3 on Mac.
  •  

    On this page I explain the oldest way of adding event handlers, the way that is even supported by the Version 2 browsers.

    The oldest browsers support only one way of registering event handlers, the way invented by Netscape. There were no compatibility problems yet, Netscape called the shots and Microsoft had to follow its lead if it wished to produce a browser that could handle JavaScript. Therefore this model works in all JavaScript browsers — except for Explorer 3 on Mac, which doesn’t support events at all.

    Registering event handlers

    In the inline event registration model, event handlers are added as attributes to the HTML elements they were working on, like:

    <A HREF="somewhere.html" onClick="alert('I\'ve been clicked!')">
    

    When a click event takes place on the link, the event handler is invoked and executes the script: an alert is shown. You can also invoke a JavaScript function:

    <A HREF="somewhere.html" onClick="doSomething()">
    

    The mix of upper and lower case in the event names (onClick, onMouseOver) is only a tradition. HTML is case insensitive, so you can use whatever case you like. In XHTML attribute names are all lower case, though, so if you use XHTML you must write onclick and onmouseover.

    Back then Netscape also decided on default actions and how to prevent them. Its model has survived the intervening browser wars and standardizations, so that it still works fine today.

    Default action

    As we all know, when the user clicks on a link the browser loads the page specified in its href attribute. This is the default action caused by a click event on a link. But what happens when you’ve also defined an onclick event handler? It should be executed, but when?

    <A HREF="somewhere.html" onClick="doSomething()">
    

    In the case of a click on a link, the event handler must be executed first. After all, when the default action takes place —new page is loaded— the old page, including the event handler, is removed from browser memory. Therefore if the onclick event handler is to be executed at all, it must be done before the default action.

    This has become an important principle of event handling. If an event causes both a default action and execution of a event handling script:

    1. the event handler script is executed first
    2. the default action takes place afterwards

    So in our example the function doSomething() is executed first, only then does the browser follow the link.

    Prevent default

    When this was decided, people started thinking about preventing the default action. In our example it should be possible to prevent the browser from loading a new page.

    Therefore the event handler can return a boolean (true or false), and false means: “don’t take the default action”. So if we change our example to

    <A HREF="somewhere.html" onClick="doSomething(); return false">
    

    the link is never followed. The function is executed and after that the event handler returns false, telling the browser not to take the default action.

    It is also possible to let the function decide whether to allow the default action. Then we have to change the example to

    <A HREF="somewhere.html" onClick="return doSomething()">
    
    function doSomething()
    {
    	return confirm('Do you really want to follow this link?')
    }
    

    This is (very simple) user interaction. The user is asked a question; if he answers ’OK’ the function returns true, if he answers ’Cancel’ the function returns false. This returned value is caught by the event handler, which in turn returns it to the event itself. If false is returned the default action is canceled — link is not followed.

    However, you cannot prevent all default actions. An unload, for example, cannot be prevented. Suppose the user closes the browser window — causing an unload event in the page in the window. If you could prevent the unloading, would that mean the window stays open regardless of the wishes of the user? No go.

    You can try to stop the unloading with Microsoft’s proprietary beforeunload event. But even then the user is asked to confirm this prevention of the default action, creating a very confusing situation. Better not to use it.

    Returning false to prevent the default action works in all browsers, it’s a basic part of event handling. Modern event handling models have added some new ways of preventing the default:

    But you don’t need to use them, a simple return false also does the job.

    window.status

    There’s one exception to the return false rule. When you change the status text of the window after the user mouseovered a link, you also want to prevent the default action — show HREF in status bar. To do this you must return true:

    <A HREF="somewhere.html"
    	onMouseOver="window.status = 'This link goes somewhere'; return true">
    

    If you don’t, the code will not work. Nobody knows why this is an exception, it’s just one of those strange things.
    (In Netscape 6.2 writing messages in the status bar doesn’t work. Fortunately this bug is solved in the subsequent Mozilla releases.)

    this

    In JavaScript the this keyword always refers to the “owner” of a function. In the case of event handlers it is very useful if this refers to the HTML element the event is handled by, so that you have easy access to it.

    Unfortunately the this keyword, though very powerful, is hard to use if you don’t know exactly how it works. I discuss its use on another page. Here I give a short summary of its use in the inline model.

    In the inline model you can send this to the event handling function as an argument. So if you do

    <A HREF="somewhere.html" onClick="doSomething(this)">
    
    function doSomething(obj)
    {
    	// obj now refers to the link
    }
    

    you pass a reference to the link to the function, which stores it in obj. Now you don’t need to search the document to find the element the user clicked on: it is safely stored in obj. Now we can do:

    <A HREF="somewhere.html" onClick="doSomething(this)">
    <A HREF="somewhereElse.html" onClick="doSomething(this)">
    
    function doSomething(obj)
    {
    	var linkTo = obj.href;
    	return confirm('Do you really want to follow the link to ' + linkTo + '?')
    }
    

    The function receives a reference to the link in the variable obj. You can now read out its href property and use it in the confirm. The trick is that you can add this event handling function to any link in the document: it will always report the href of the actual link that has been clicked on.

    Continue

    If you wish to go through all event pages in order, you should now continue with the Traditional event registration model page

    Home