Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery add() function and the context of jQuery objects

Tags:

jquery

object

Given the following HTML example...

<div id='div1'>div one</div>
<div id='div2'>div two</div>

...I found that the following jQuery code...

$('#div1').click(function() {

    var $d = $(this);    // Using 'this' instead of '#div1'

    $d.add('#div2').remove();
});

...would not add #div2 to the set referenced by $d, but this code...

$('#div1').click(function() {

    var $d = $('#div1');    // Using '#div1' instead of 'this'

    $d.add('#div2').remove();
});

...successfully added #div2.

Upon consulting firebug, I found that using $(this) gave the jQuery object a context of #div1, but doing $('#div1') gave the object a context of document.

Given this information I tried...

var $d = $(this, document);

...and the add() function worked as expected.

So here's the question. Could someone please explain to my why a different context is assigned when using $(this) vs $('#div1')?

like image 802
user113716 Avatar asked Apr 13 '10 01:04

user113716


1 Answers

Edited to better address your question:
First, look at the relevant code here, this is how jQuery handles the $() call. When you're passing a DOM element (which this is, it's the div itself) the context is the DOM element itself, this better allows handling of document fragments, etc. When you pass a string, the default context is document (because it's the top ancestor to search from). Remember a $(selector, context) is actually calling context.find(selector) under the covers, so it makes sense to start at document if nothing's specified.

Note: you can always check the context, it's an available property, like this: $(this).context

For the .add() behavior:
.add() uses the same context for selecting as the jQuery element you're adding to, so what you're seeing is the expected behavior. For a better description, see how .add() is written:

add: function( selector, context ) {
    var set = typeof selector === "string" ?
                jQuery( selector, context || this.context ) :
                jQuery.makeArray( selector ),
                all = jQuery.merge( this.get(), set );

    return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
            all :
            jQuery.unique( all ) );
    }

Note how it uses the current context if none is passed. To override this though, it accepts a context, to which you can pass document and get the result you want, like this:

$('#div1').click(function() {
   $(this).add('#div2', document).remove();
});
like image 95
Nick Craver Avatar answered Oct 14 '22 09:10

Nick Craver