http://jsfiddle.net/garnwraly/sfrwU/2/
given HTML of only
<li>
<button id="bam">click</button>
</li>
and this script
$('body').on('click', 'button', function (e) {
//console.log( e.currentTarget == $('button')[0] ); //true;
//console.log($('li').is('li:first')); //true
console.log($(e.currentTarget).parent().is('li:first')) //false
console.log($('button').parent().is('li:first')); //true
console.log($($('button')[0]).parent().is('li:first')); //false
});
why is $(e.currentTarget).parent().is('li:first')
false?
After step debugging through the jQuery code as this ran, this turns out to be an issue with the way the jQuery()
method is used within the is()
method. As we know, you can pass a context into the method, and internally, this context is being used with the is()
method (and is being set differently for the various selectors).
When $(e.currentTarget)
is used, the context is set to the button that triggered the event. While when $('button')
is used, the context is set to the Document
object. This makes sense when you think of how these selectors need to be scoped.
Here is the relevant part of the is()
method:
jQuery( selector, this.context ).index( this[0] ) >= 0
Based on that, when run as $(e.currentTarget), the call to the jQuery()
method is evaluation to:
jQuery("li:first", "button#bam").index( this[0] ) >= 0
Which is obviously returning -1, and reporting as false
I think it may be that :first
only cares about matching - in the case that the jQuery object is constructed from a DOM element, there's no selector matching going on. Note that
console.log($(document.getElementById('bam')).is(':first'));
also logs false
.
I don't feel that the behavior is correct, and a bug should probably be logged, but even if it worked properly I don't think that in this case testing :first
really does any good. If you use .parent()
to navigate up the DOM to the parent node starting from a single element, then it's pointless to ask whether the parent is the first element - there'll always be a parent (except from the DOM root of course), and always just one.
If you do it with :first-child
, which would actually be interesting but not necessarily relevant, then it works as one might expect because :first-child
is actually about the structure of the DOM. The :first
qualifier is just about being the first matched element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With