When "This" Is Not What You Think
. These methods are very useful when setting event handler functions. To better understand the problem they solve, take a close look at the following code, which creates a Person
object and sets its displayFirstName
method as the event listener for the <div>’s click event:
<!-- HTML -->
<div id="elem">Click Here</div>
var person = new Person("John", "Brown", 20);
$("elem").onclick = person.displayFirstName;
You might expect John, the first name, to display when the user clicks on "Click Here." If you try it, however, you will notice that undefined is displayed instead. Why? Because when you write $("elem").onclick = person.displayFirstName you're more or less saying replace the body of the <div> onclick function with the body of the person.displayFirstName function, which is alert(this.firstName);.
The problem is when onclick gets called, the this keyword does not refer to Person anymore. It points to the <div> elementwhich has no firstName property! Prototype elegantly resolves this problem by using the bind method as follows:
$("elem").onclick = person.displayFirstName.bind(person);
Now the this keyword refers to the Person class. The expression of that line of code in words would be replace the body of the <div> onclick function with the body of person.displayFirstName and bind the person object to the this keyword. The bindAsEventListener function does the same thing, plus it passes the event object to the called function in a cross-browser manner.
Iterating with Prototype
for(var i = 0; i < languages.length; i++)
Here is the same example using the each method of Enumerable:
The each methodlike many other Enumerable methodstakes a function as its argument. The function in this case is called iterator. The first parameter (value) is the value of the current element, while index is the current index of the iteration. You can also omit the index parameter if you don't need it. For example, the following code has the same effect as the previous one:
Although each is not as useful as the other funtionalities covered so far, Enumerable includes many functional methods that will make you glad you chose Prototype as a framework. For example, you can use the grep method to select a subset of an array that matches a regex pattern:
This code means select all the elements that begin with the word Java and are followed by any character, and display each item found.
If you don't need complicated filtering, you can just use the select method as follows:
var prices = [10, 12, 25, 28, 50, 100];
// lowPrices = [10, 12, 25]
var lowPrices = prices.select( function(value)
return value <= 25;
It selects the elements for which the iterator function returns true.
With Prototype, you can use the Event object to handle events in a cross-browser fashion. For example, you can use it with the observe method to observe an element. The observe method takes four parameters:
- The element to observe
- The event type (click, blur, keyup, and so on)
- The function to call when the event occurs
- The last parameter, which indicates whether the capturing phase must be used
Here's an example:
<!-- HTML -->
Event.observe($("elem"), "click", displayAlert, false);
alert("You clicked the element");
You can stop observing an element by calling the stopObserving method as follows:
Event.stopObserving($("elem"), "click", displayAlert, false);
Another useful object is Element. For example, you can use its toggle method to toggle an element so that if it is visible and you toggle it then it will be hidden, and if it is hidden and you "toggle" it then it will show:
<!-- HTML -->
You can toggle me by clicking the button above.
Two other effective methods are show and hide, which you use to show and hide an element, respectively.
At this point, you're probably ready for some AJAX action. Prototype provides a bunch of handy tools to develop Web 2.0 applications and sites.