|
Event Handling in Netscape Break out your favorite version of Netcape. We're using all Netscape this lesson. Once you do, come on back to this lesson. If you have it open already, carry on. In the UserActive JavaScript learning labs we talked a lot about events and event handlers. We used things like onMouseOver=someFunction() to cause a JavaScript to run when the mouse passed over the object we applied that event handler to. DHTML, while it still supports these events and event handlers, provides us with a whole new set of tools to use for handling events, and gives us some new events to use. The main thing that netscape has added is Event Capturing. With Event Capturing we can catch any event that may happen while the document is loaded. This can include all of the mouse events like mousedown, mouseup, mousemove, dblclick, etc. as well as the keyboard events like keypress, keydown, etc. In Netscape some the events are captured by the object itself, and some of them are not. For instance, in a layer or stylesheet we can use onMousedown, BUT we cannot use onClick inside the tag. But what do we do if we want to execute some script when someone clicks on a layer?? Enter event capturing. The first thing we're going to talk about is the "event" object. In the past, when we said onMouseOver=someFunction() inside an object in a document, someFunction() was called. someFunction() really didn't know anything about how it was called...it didn't know what button was clicked, where on the page the mouse was, or anything...all it knew was that somewhere on the web page an event handler was triggered and that someFunction() was supposed to run. The "event" object changes all of that. By accessing the "event" object, we can find out all sorts of nifty information about how the event was triggered. Before we start talking about how to use this new information, I'd like to show you a list of what information is available to us. Below is a table borrowed from Netscape's developer site...I have added some comments in blue. So we can find out all of this nifty stuff about our events! All we have to do is add some code to our function "someFunction()" to do it, and make sure we put in the event handler onMouseOver=someFunction() right? Let's talk about how we can capture our events without using the event handlers (onMouseOver=someFunction()) that we're used to. I'm going to do an example of how to capture the onClick event of our document. Then we're going to play with some of that new information we can use to see how the event object works. After we're all done with that, we'll talk about the other events that you can capture. Type the follow code into CodeRunner below:
Before we even talk about how this works, go preview this code and click on the document. You should see an alert pop up. OK...what you just saw was exactly like if we had used the onclick event handler in the <body> tag of the document. But, the way we did it was completely different. Before we worry about all of the neat new things we can do with the new event model, let's see how events are "caught". In our script, the first thing we did (in blue) was make a JavaScript reference to the document object, and then call the captureEvents() method. The captureEvents() method is a method available to all object that JavaScript can reference (i.e. document, window, form input, etc.) This method tells the browser that it needs to pay attention to a certain type or types of events. The parameter that we pass to the captureEvents() method, Event.CLICK, tells the browser to look for the CLICK event. Notice that we had to say Event.CLICK. This is because the CLICK event type is contained in the Event object. In purple we told the browser what to do when the CLICK event happened in the document. This should look very similar to the event handlers that you used in the past, except now we are using them in JavaScript context. We told the browser which object to watch, and when it saw the "CLICK" event, to call a certain function. Notice that we said "document.onclick...not "document.click". Why do we prepend (add to the front) that "on" to our event name? I don't know, but we have to. I'm going to say that a lot during this tutorial. Anyway, with "document.onclick = showme;" we tell the browser to, when the user clicks on the document, run the function named "showme". Notice that the name of the function doesn't have "()" parentheses after it. This is intentional...when we are defining an action for an event we don't append parentheses to the name of our function. Finally, we are done telling the browser how to handle the event, and we can define the function that will do the actual work when the even is triggered. Notice in red that our function expects a parameter that will be held in the variable "e". But, we aren't passing any paramters to our function...in fact we didn't even include parentheses in our event handler definition! Well, it's all OK...you see, when the browser handles an event in this way, it automatically passes an Event object with all of the information about our event as a parameter to our function...that "e" variable is going to hold an event object. This script doesn't do anything with that event object, so let's do something with it. The very first property of the Event object in the table that I showed you earlier was "type" which tells use what type of event triggered this reaction. As we all know, the event type that we're working with right now is "CLICK"...let's prove it using the type property of our event object. Type the follow code into CodeRunner below:
Go try it...it tells us when we click the document that our click event triggered the script that popped up the alert. You see, when we click on the document, the browser calls the "showme()" function, and passes an event object containing all of the information about the event that triggered this script as an argument. The event object is stored in the variable "e". So, by calling "e.type" we get a value representing the type of event that triggered this script...in this case "CLICK". Let's play with some of the other event object properties. Let's say we want to find where on the page the mouse clicked. To do this we would need to get the pageX and pageY properties from the event object: Type the follow code into CodeRunner below:
This script alerts us about the position of the mouse when the button was clicked, in the syntax of "Page X Coordinate,Page Y Coordinate". Nuff said. Go play with some of the other event object properties just put an e. in front of the properties in the list (like e.type). Some of the properties are relevant to a mouse click, some aren't...find out which ones are which. Now, let's say we want to catch 2 different event types in our document (yes, I know I haven't told you all of the available event types, but I will if you stick with me.) Let's capture both the CLICK event, and the MOUSEMOVE event (MOUSEMOVE is triggered when the mouse moves around over an object.) Here's the code...we'll talk about it in a minute: font size=2 face="arial,helvetica">Type the follow code into CodeRunner below:
Preview this. When you go try it, you should be able to do 2 things. When you move your mouse around on the page, the status bar should show the pageX,pageY coordinates of your mouse pointer. When you click your mouse, that same alert as before should pop up showing you the coordinates of your pointer when you clicked. The key to being able to capture multiple events in a single object (in this case document) is the captureEvents() method. Somehow we had to tell the browser to capture multiple events. We did this by entering all of the events we wanted to capture by a |...this is called the "pipe" character. This is the same character you use in JavaScript "if" statements to signify the "or" operator as in "||". We can put as many event types that we want to capture as we want into the captureEvents() method as we want as long as we seperate them by the | character. Once we've captured the MOUSEMOVE and CLICK events, we just treat them the same as we did before...we add a line of JavaScript telling the browser what function to call when that event is triggered. That's what I did in blue. Now you may be wondering, "Why the heck is that 'type' property available from the event object??" Well, suppose we want to handle different types of events all in one function. We would need to find out what event triggered the function to decide what code to execute right? Right. Let's do that: font size=2 face="arial,helvetica">Type the follow code into CodeRunner below:
What did we do? Well, we told the browser to run the same function - showme - for both the CLICK and MOUSEMOVE events. Then, in the showme function we tested to see which event had triggered the function by using the type property, and ran the appropriate code. In effect, we use 1 function to do the job that 2 functions were doing before. Now, you know we have the captureEvents() method at our disposal. you might have wondered, "Why do I have to tell the browser to capture events?" Great question! The reason is that in this event model, we can start and stop capturing events at any time. For instance, let's say that in our previous example we only wanted to react to the "CLICK" event one time...that is we will only pop up an alert the first time the user clicks on the document. Once we have popped up that alert, we want the browser to stop paying attention to, or "capturing", the CLICK event. To do this, we use the "releaseEvents()" method. See below: Type the follow code into CodeRunner below:
Go try it...move your mouse around and see the coordinates in the status bar...click and see the alert...then move your mouse around and see that the coordinates don't change anymore. This is because we canceled the mousemove event with releaseEvents. Why do we care? Well, if we were making Drag and Drop CSS's, we would only care about the MOUSEMOVE event inbetween the times that the mouse was clicked down and when it was released. We can captureEvents(Event.MOUSEMOVE) when the mouse button is pressed, and releaseEvents(Event.MOUSEMOVE) when the mouse button is released, and then we are only having the browser pay attention to MOUSEMOVE when we want to use it...it saves CPU time and also solves problems with interference with other events as you'll see when we do Drag and Drop stuff. OK...I told you I'd tell you all of the event types you can use. We aren't going to take the time to try them all...play around with them and figure them out :) Here they (list borrowed from Netscape site) are along with my comments on what objects they are typically used for: Abort
KeyDown - Window
MouseUp - about anything
Blur - Anything
KeyPress - Window
Move - Window (when the user move the window)
Click - Anything
KeyUp - Window
Reset - Forms
Change - Form Inputs
Load - Document
Resize - Window (when the user resizes the window)
DblClick - Anything
MouseDown - Anything
Select - Form Input, Window, Frame, Layer/CSS
DragDrop - Window (when user drags an icon onto Netscape)
MouseMove - Anything
Submit - Form
Error
MouseOut - Anything
Unload - Document
Focus - Anything
MouseOver - Anything
Hopefully, we'll use all of these events before we are through with all the the DHTML lessons. At least we'll try!
Capturing a click event on a layer in Netscape Since Netscape layers don't have the onClick method, we have to use Event Capturing and a trick using onMouseover to be able to respond to someone clicking on a particular stylesheet or layer. So I thought we should go through an example of doing something like this. In the next example we'll make a layer that has the onMouseover event handler in it (Netscape's layers have the onMouseover event handler but not the onclick). Type the follow code into CodeRunner below:
Preview this and click on the the two colors and well as the background. It shouldn't do anything if you click on the white background. What did we do here? We defined two functions activate() and deactivate(). When the mouse moves over the layer is triggers the event handler onMouseover which calls activate("red") which sets a variable called dosomething to true. This is called setting a flag. now when you click your mousedown if the flag "dosomething" is set to true it pops up an alert. Also notice that we put a return false; in the function handling the event. Don't underestimate this. This cancels the event. Try taking it out and see how it responds. NOTE: In netscape we cannot do this with stylesheets, only layers. This is because Netscape doesn't provide stylesheets with any events not even onmouseover. In a later lesson on The cross browser library we will discover a work around for this. Using the Keyboard events I thought we should pay particular attention to the keyboard events. They are keydown, keyup and keypress. These are just slightly different because we may want to use different keys for different purposes so we will need to know which key was pressed and respond accordingly. Also we may want to set our page up so that if they type Cntrl S they can search the page or something. This would be an example of using modifier. You've seen the difference between keypress and keydown. If you have ever been typing on a computer and held a key down you know that it will type the same letter over and over again without you having to let up on the key. This is a keypress event. It is useful if you want to do something over and over again while they hold the key down. Whereas keydown only calls the event handler once no matter how long you hold the key down. You have to let the key back up to call keydown again. As for keyup, that only gets called when you let a key up. Here is an example of using the keydown event. Type the follow code into CodeRunner below:
Preview this. Try typing many different charaters. It will alert you with the ASCII decimal character code and the corresponding character. Since we can use string.fromCharCode(e.which) we can simply use the actual character for all of the charaters except for the modifier keys like shift, Ctrl, etc. Did you notice though that the ENTER KEY is 13 and that the Back Space key is 8. These two you will have to remember because there is no ascii character for them. The reason we called the focus(); event is because otherwise you would have to click on the window before the keyboard events would be captured. Suppose you want to call a function when the user holds down the control key and presses P? We can do that! Type the follow code into CodeRunner below:
|