AJAX In Action [72]
myDomElement is any DOM element that we have a programmatic handle on. showAnimatedMonkey is a function, defined as function showAnimatedMonkey(){
//some skillfully executed code to display
//an engaging cartoon character here
}
Licensed to jonathan zheng The Controller in an Ajax application 135 that is, as an ordinary JavaScript function. Note that when we assign the event handler, we pass the Function object, not a call to that object, so it doesn’t have parentheses after the function name. This is a common mistake: myDomElement.onclick=showAnimatedMonkey(); This looks more natural to programmers unaccustomed to treating functions as first-class objects, but it will not do what we think. The function will be called when we make the assignment, not when the DOM element is clicked. The onclick property will be set to whatever is returned by the function. Unless you’re doing something extremely clever involving functions that return references to other functions, this is probably not desirable. Here’s the right way to do it: myDomElement.onclick=showAnimatedMonkey; This passes a reference to our callback function to the DOM element, telling it that this is the function to invoke when the node is clicked on. DOM elements have many such properties to which event-handler functions can be attached. Common event-handler callbacks for GUI work are listed in table 4.1. Similar properties can be found elsewhere in web browser JavaScript, too. The XMLHttpRequest.onreadystate and window.onload, which we have encountered already, are also event handler functions that can be assigned by the programmer. Table 4.1 Common GUI event handler properties in the DOM Property Description onmouseover Triggered when the mouse first passes into an element’s region. onmouseout Triggered when the mouse passes out of an element’s region. onmousemove Triggered whenever the mouse moves while within an element’s region (i.e., frequently!). onclick Triggered when the mouse is clicked within an element’s region. onkeypress Triggered when a key is pressed while this element has input focus. Global key handlers can be attached to the document’s body. onfocus A visible element receives input focus. onblur A visible element loses input focus. There is an unusual feature of the event handler functions worth mentioning here, as it trips people up most frequently when writing object-oriented JavaScript, a feature that we will lean on heavily in developing Ajax clients. Licensed to jonathan zheng 136 CHAPTER 4 The page as an application We’ve got a handle on a DOM element, and assigned a callback function to the onclick property. When the DOM element receives a mouse click, the callback is invoked. However, the function context (that is, the value that variable this resolves to—see appendix B for a fuller discussion of JavaScript Function objects) is assigned to the DOM node that received the event. Depending on where and how the function was originally declared, this can be very confusing. Let's explore the problem with an example. We define a class to represent a button object, which has a reference to a DOM node, a callback handler, and a value that is displayed when the button is clicked. Any instance of the button will respond in the same way to a mouse click event, and so we define the callback handler as a method of the button class. That’s a sufficient spec for starters, so let’s look at the code. Here’s the constructor for our button: function Button(value,domEl){ this.domEl=domEl; this.value=value; this.domEl.onclick=this.clickHandler; } We go on to define an event handler as part of the Button class: Button.prototype.clickHandler=function(){ alert(this.value); } It looks straightforward enough, but it doesn’t do what we want it to. The alert box will generally return a message undefined, not the value property that we passed to the constructor. Let’s see why. The function clickHandler