Consider that you want to add an ajax functionality to many links on your page.
<a href='http://domain/purchase/car' class='purchase'>Car</a>
<a href='http://domain/purchase/bag' class='purchase'>Bag</a>
<a href='http://domain/purchase/laptop' class='purchase'>Laptop</a>
and
<a href='http://domain/sell/car' class='sell'>Car</a>
<a href='http://domain/sell/bag' class='sell'>Bag</a>
<a href='http://domain/sell/laptop' class='sell'>Laptop</a>
Now you might define some variables to refer to these groups of links in your JavaScript code:
var purchaseLinks = $('.purchase'),
sellLinks= $('.sell');
Well, enough story ;).
You can look at the problem in this fiddle and this one.
According to jQuery’s add() documentation, the return value is a new jQuery object. And again, AMAIK inside a function handler that is attached to an event of a jQuery object, this referes to the DOM element.
Why by using add() method, this of the handler function refers to the document? I don’t understand it. I can’t match my knowledge to make a logical perception. In other words:
jQueryObject1.click(function(){
// Here, $(this) is the jQuery object
});
jQueryObject2.click(function(){
// Here again, $(this) is the jQuery object
});
jQueryObject1.add(jQueryObject2).click(function(){
// Here $(this) refers to the Document, why?
// I think jQueryObject1.add(jQueryObject2) should equal jQueryObject3
});
UPDATE:
Thanks for your answers. I again refer readers to Live is Deprecated page, so that everyone can improve.
The problem in your fiddle is the use of
.live(). The jQuery docs state:Fortunately for everyone, the
.live()method is deprecated, so you don’t have to worry about stuff like that anymore. You can useoninstead and take advantage of event delegation.Update (following the comment by @Esailija)
This is what actually happens. You call jQuery here:
That results in a jQuery object, which has a
selectorproperty. You then call.add(), which in turn calls the internalpushStackmethod:The
pushStackmethod creates the new jQuery object. It gets called with only one argument. Here’s the relevant parts of the method (note thatnameandselectorare bothundefinedin our case):Also note that
this.contextis now the document (since your original jQuery object didn’t specify a context, the highest possible context is assumed).So the newly formed element set doesn’t have a
selectorproperty, and has the document as its context. When we then call.live(), jQuery simply calls.on()like this:And there we can see the problem. The context is the document, and there is no selector, so the event handler gets bound to the document. The above line in our case is effectively this:
And you can see this by the fact that your
alertis triggered by clicking anywhere in the document, not just on the links.The moral of the story? Stop using
.live()!