jQuery Intermediate - 1
Earlier while learning jQuery, I was confused about the concept of the 'this' keyword. Sometimes it refers to a DOM element and other times it can refer to a jQuery object. Without knowing how to tell the difference, the work was more like an exercise in guessing than programming.
Under normal circumstances, the 'this' keyword refers to a DOM element. It is most commonly used inside a callback function, such as when binding to an event, iterating over elements with the each function, using animations, using filters, and various other functions.
Numerous functions inside jQuery can accept callback functions that you might not have noticed before. For example, jQuery has two functions for fadeOut. One function takes only a speed argument, but the other function accepts a speed argument and a callback function. After the DOM selection fades out, the callback function provided is triggered, and at that point the this keyword refers to the selected DOM element. If more than one element is selected to fadeOut, the callback is triggered after the corresponding element fades out. Here are several examples of using the 'this' keyword:
1. //Binding to an event
2. $('a').click(function() {
3. //this refers to the anchor DOM element
4. console.log("this.href = '" + this.href + "'");
5. })
6.
7. //Iterating over elements from a jQuery selection
8. $('a').each(function() {
9. //this refers to the anchor DOM element
10. console.log("this.href = '" + this.href + "'");
11. });
12.
13. //Fading DOM elements from a jQuery selection
14. $('a').fadeOut('slow', function() {
15. //this refers to the anchor DOM element that was just faded out
16. console.log("this.href = '" + this.href + "'");
17. });
As you can see, in most scenarios involving the this keyword, it refers to an actual DOM element. However, the main area in which you need to be careful with the this keyword is when you write a jQuery plug-in. The this keyword immediately inside a jQuery plug-in refers to the jQuery object from the selector used when calling the plug-in. You need access to the jQuery object because the official guidelines for jQuery development suggest returning the jQuery object to support chainability in your jQuery plug-in. (If you are unfamiliar with chainability, I’ll touch on the concept later in the section “Caching Selectors or Chaining.”) The following code shows an example of using the this keyword in a plug-in.
1. (function($) {
2. $.fn.myPlugin = function() {
3. //this refers to the jQuery object that was a result of the jQuery selection
4. console.log("this.attr('id') = '" + this.attr('id') + "'");
5. this.each(function() {
6. //this refers to a DOM element that is part of the jQuery selection
7. console.log("this.id = '" + this.id + "'");
8. });
9. return this;
10. }
11. })(jQuery);
Instead of using the previous code, you might more frequently encounter a technique that returns the each function immediately instead of returning on a subsequent line. Take a look at the following:
1. (function($) {
2. $.fn.myPlugin = function() {
3. //this refers to the jQuery object that was a result of the jQuery selection
4. console.log("this.attr('id') = '" + this.attr('id') + "'");
5. return this.each(function() {
6. //this refers to a DOM element that is part of the jQuery selection
7. console.log("this.id = '" + this.id + "'");
8. });
9. }
10. })(jQuery);
Here’s another scenario in which the this keyword can point to something other than the DOM element or jQuery object. In jQuery 1.4.2, a new method was introduced called proxy. This method allows you to define what the this keyword refers to inside an event handler.
The following code shows the creation of an object literal, including a userNameof “miteshvmehta” and a tweet method that alerts the userNameoff of the thiskeyword.
As you might expect, if I call twitter.tweet(), you’ll see an alert displaying “Hello miteshvmehta”.
1. //Object Literal
2. var twitter = {
3. userName: "miteshvmehta",
4. tweet: function() {
5. alert("Hello " + this.userName);
6. }
7. };
8.
9. // Call tweet() method off of twitter Object Literal
10. twitter.tweet(); // alert’s “Hello miteshvmehta”
However, the result is different if you pass a twitter.tweet as the event handler parameter to one of jQuery’s event helpers or to the bind or live method. Instead of seeing “Hello miteshvmehta”, as you might expect, you see “Hello undefined”. This happens because the this keyword references the DOM element that was clicked rather than the twitter object literal.
To change the functionality to show the alert “Hello miteshvmehta” instead, you can use the new proxy jQuery method. Instead of passing twitter.tweet directly into the click argument, you can now wrap it inside the $.proxy() method. The first parameter of $.proxy() is the event handler function (in our cast, that is twitter.tweet), and the second parameter is the context that you want the this keyword to reference, which is the twitter object literal.
You can also use an alternate syntax in which the first parameter is the context (which is the twitter object literal) and the second parameter is a string representing the method that you want to represent the event handler off of the context, in our case “tweet”.
1. //Object Literal
2. var twitter = {
3. userName: "miteshvmehta",
4. tweet: function() {
5. alert("Hello " + this.userName);
6. }
7. };
8.
9. /* Option #1: jQuery.proxy( function, context ) */
10. $("#update2").click( $.proxy( twitter.tweet, twitter ) );
11.
12. /* Option #2: jQuery.proxy( context, name ) */
13. $("#update3").click( $.proxy( twitter, "tweet" ) );
No comments:
Post a Comment