jQuery's this: demystified
More often that not, in my early dabbling with jQuery and more advanced JavaScript, I found I would constantly get confused over the meaning of "this" in jQuery and my own new libraries.
Hopefully this quick guide can help clarify those confusing moments, because once you've got it, it's simple as pie.
What is "this"?
In many object-oriented programming languages, this (or self) is a keyword which can be used in instance methods to refer to the object on which the currently executing method has been invoked.
Source: http://en.wikipedia.org/wiki/This_(computer_science)
jQuery's this
There are really two main contexts of 'this' in jQuery. The first refers to a to a DOM element, and the second to a jQuery object.
Example of this as a DOM element
'this' is a DOM element when you are inside of a callback function (in the context of jQuery), for example, being called by the click, each, bind, etc. methods.
The following code searches for anchor links with the class of 'newTarget' and sets the 'target' attribute to '_new' (which is a trick to create strict XHTML while still having some links open in a new window).
In this example we are also going to perform a double check to ensure links to the same domain don't open in a new window using the this object.
$('a.newTarget').each(function() { // <- our anonymous callback
// check the DOM attribute 'host' on this
if (this.host != window.location.host) {
// create a jQuery object using the current DOM element
$(this).attr('target', '_new');
}
});
Example of this as a jQuery object
'this' is a jQuery object when you are inside your own jQuery functions. Note that the result of a selector query (i.e. $('a') ) is a jQuery object, which is an array of the matched DOM elements (imagine jQuery is an array with bells on).
jQuery.fn.newTarget = function() {
// 'this' is a jQuery object at this point - with all the jQuery functions
return this.each(function() { // return so we don't break the chain
// now we are inside of a jQuery function, the DOM element is the context
// so 'this' has changed to become a DOM element.
if (this.host != window.location.host) {
$(this).attr('target', '_new');
}
});
};
Finishing up
This is far from comprehensive, but equally there's very little to the logic. So long as you remember the context of 'this' changes when moving in and out of object methods then you're on your way.
If you're still not sure, get your hands on Firebug and add 'console.log(this)' within your code to interrogate and understand what 'this' is at that point in your code.
If this still doesn't make sense or I've got it terribly wrong - or you're suddenly enlightened, please do let me know - and I'll do my best to help.
Thanks for $(this)!
Great article. I have a persistent problem that maybe you can help with. How do you call Jquery from with a custom Javascript object and reference the object from within the Jquery callback function?
Example:
How do you pass a reference to the customClass since "this" is replaced by Jquery? I haven't found an answer yet. I haven't even been able to find a single example of code where someone tried to call Jquery from with a custom Javascript object. Am I going about this all wrong?
@Tyson - your code is fine. The solution is just to cache a copy within your function call.
e.g.
Thanks for the code example! You just saved me hours of pain trying to figure out how to use jquery inside of a custom object method.
I quickly read thru your article and I gained a very valuable lesson. I did not know 'this' could change contexts like that. You write very articulately and precise. Thanks a bunch. I wish you the best at whatever u r pursuing.
great article
i have got a problem
$('.delete').click(function(){
$.post("test2.php",{id:txt},function(){
this...somecode});});
if i want to refer "this" to the element $('.delete'), what shall i do?
@Jian - you need to cache the element within the click function. e.g.
I tried this but it did not work
$('.delete').click(function () {
var t = this;
$.post("test2.php", { id : txt }, function () {
$(this).html("ready");
});
});
@Carlos, I've no idea what you're trying to achieve without any context, but here's a guess:
This code won't act as you expect:
Because
thisisn't what you think it is. Either run the selector again or point it to the right variable, e.g.Hi, UR artice userful, but I get some probelm, can U help me to fix it ? thanks.
when I user jQuery ajax function.
..............
.............
some code over here.....
@Vincent - I'm not sure if your comment cut short or not, but assuming it didn't I would suggest the problems(s) may be here (keeping in mind I don't have much context to go with):
1) Using 'xxxx.prototype.callback' - might be simpler and lighter on the DOM(?) to just use something like:
2) Since the XML is just data and not functional code, I would expect this:
To break because the XML 'item' node won't have a method called createMarker on it.
I would strongly recommend using [Firebug](http://getfireubg.com) with the 'break on errors' options (in the script tab) turned on.
Good luck.
[...] the “this” keyword in javascript (specifically, using the jQuery library–Thanks, Remy Sharp!), I stumbled across his Last.fm “Recent Albums” widget. They also offer this little [...]
[...] started to look at the this keyword to see if that would help. Learning jQuery’s What is this? post clarified a lot of my [...]
As pointed on another comment, this article brings valuable knowledge to those who are starting to 'uncarefully' mix DOM and JQuery. Thanks.
You can still use this type of code which can use the element's "this", however you still need an id:
This was a very useful article. It definitely clears up the weird and changing jQuery behavior of the keyword 'this' in callback functions and own jQuery functions. Thank you! Ódýr Vefhýsing.
Thanks Remy. A simple article but just what I needed to get started with jQuery!
Thanks Buddy, you have saved my time. I was mucking around with 'this' problem inside a jQuery function. Thanks alot.
Hello,
sorry, but simply cant get this to work. I have a couple of DIV´s with class ".day_group", within these div´s one -heading and one -list that is by default hidden. What I am trying to do is to make the -list to show when you click the - but only in this -section.
I tried this, but this opens all -lists, of course. Tried with "this", but no go. Pls, anbody help. Thx!
$('foo') is an array of matched elements, as you say, but what about when no elements match? If I call $().myPlugin(), what kind of object is 'this' in the myPlugin function?
I'm asking because I am trying to detect that situation happening from within my plugin, but I cannot for the life of me see how to test for that. My guess is that 'this' is an empty jQuery object, but how would I test for that? How would my plugin be able to tell whether it was called up using $().myPlugin() or $('foo').myPlugin()?
It this boils down to this problem: how can I tell whether a jQuery object (which I believe is what 'this' always will be), inside my plugin function, has matched any elements or not?
Thanks!
Regarding my question, I think I have found the answer (is it not always the case when posting a question, that the answer is discovered?):
The three instances I wanted to detect, along with the condition to detect them, are:
1. $().myPlugin()
this.length == 1 && this[0].nodeName == '#document'
2. $('#invalid-selector').myPlugin()
this.length == 0
3. $('#valid-selector').myPlugin()
this.length > 1 || (this.length == 1 && this[0].nodeName != '#document')
Hope that helps someone! Sorry if it is not *entirely* relevant to the original post.
this;
$(this)
can u tell me the returning object in these cases
I was having the same problem as Tyson, and had spent hours trying to find a solution. I'm in the process of writing my first decent sized OOP application, and I was tearing out my hair trying to figure out why 'this' wasn't doing what it should within the jQuery ajax method. Thanks for a great post.
Jepp, as Tyler and Cody it fixed my problem when using colorpicker plugin on several input fields. (If you try my site don't hang me for the jquery design i'm borrowing while developing. Its just a very bad wysiwyg website generator )
Hey thank you, but I can't use your solution in this Script.
As href I'll get 'undefined'. What can I do? Thank you very much!
//edit: Just I've found a Solution: