Why does the :odd
selector not work when I pass it into the remove(selector)
function? According to the documentation it should filter the already selected set of items which in this case is the li
's.
<ul id='list1'>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
<ul id='list2'>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
$(document).ready(function() {
$('#list1').children(':odd').remove(); // works as expected
$('#list2').children().remove(':odd'); // does not work
});
Result
-One
-Three
-One
-Two
-Three
-Four
It's actually a bug: http://bugs.jquery.com/ticket/13721
And was fixed 17 days ago in jQuery 2.0.
The problem was that it was checking to see if each element matched the selector:
for element in matched_elements:
if element matches the selector:
remove element
:odd
only works in the context of a set of matched elements, so none of those elements individually were odd. Similarly, if you changed it to :even
, all of them would get deleted.
The selector passed to remove
used to be matched on the fly, that is, testing each element against the selector and removing it when matched, one element at a time. (source code)
This behavior was changed in jQuery 2.0, which now applies the selector filter before doing the removal. See:
#13721: remove(“:nth-child(1)”) works differently than filter(“:nth-child(1)”).remove()
(edit: correction on the resulting behavior explanation, @Blender is correct). In this case there's no matching as each element used to be checked against the selector individually.
Therefore the :odd
selector would never match as all elements would be considered as at the jQuery object's index 0
(which is what :odd
/:even
checks) when tested against the selector. This explains why :odd
never matches and :even
would match all elements.
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