I want to select all the li's except the first child and all the li's that don't contain: ab 2
so, if my list was:
<ul id="list">
<li>1</li>
<li>ab 1</li>
<li>ab 2</li>
<li>ab 3</li>
<li>ab 4</li>
</ul>
it will be:
<ul id="list">
<li>1</li>
<li>ab 2</li>
</ul>
I tried:
$("#list").find("li:not(:first-child), li:not(:contains('ab 2'))").each(function () {
var current = $(this);
current.css('display', 'none');
}
but all my list is gone..
I want to select all the li's except the first child and all the li's that don't contain: ab 2
so, if my list was:
<ul id="list">
<li>1</li>
<li>ab 1</li>
<li>ab 2</li>
<li>ab 3</li>
<li>ab 4</li>
</ul>
it will be:
<ul id="list">
<li>1</li>
<li>ab 2</li>
</ul>
I tried:
$("#list").find("li:not(:first-child), li:not(:contains('ab 2'))").each(function () {
var current = $(this);
current.css('display', 'none');
}
but all my list is gone..
Share Improve this question edited Jul 27, 2013 at 11:35 Alon Shmiel asked Jul 27, 2013 at 11:27 Alon ShmielAlon Shmiel 7,12127 gold badges95 silver badges140 bronze badges 1-
2
Your question is a bit weird. You say you want to select all the
li
s except the first and the one containing 'ab 2'. You say: 'it wil be...' but that's the exact opposite. – putvande Commented Jul 27, 2013 at 11:50
9 Answers
Reset to default 5This should be fast:
$("#list li")
.slice(1) // exclude the first
.not(':contains(ab 2)') // exclude all "ab 2"
To remove them, just call .remove()
or .hide()
at the end, no need to loop.
DEMO: http://jsfiddle/tY4cm/
Here is a jsPerf of different solutions posted here: http://jsperf./single-selector-vs-filter-perf/2
To remove everything but the first child and any LI with ab 2
, do :
$('#list li:not(:contains(ab 2), :first-child)').hide();
FIDDLE
Not sure about the contains functions:
$("#list li:gt(0)").not(":contains('ab 2')").each(function(){
// code
this.style.display='none'; // try to use native JS where possible
});
If hiding is the only thing you want to do, don't loop, just hide:
$("#list li:gt(0)").not(":contains('ab 2')").hide();
Performancewise you could test if this would be faster:
$("#list").find("li").not(":first-child") // or
$("#list li").not(":first-child") // or
$("#list li:not(:first-child)")
With the filter added to it (didnt do that for readability)
Try this:
$("#list li").each(function () {
var $this = $(this);
if($this.text() == 'ab 2' || $this.is(':first-child')) { return; }
// your code
}
If you'd do an each
function anyway, I see no reason to use such a plex query string.
The ,
selector works as an or; i.e. all elements which are either not the first child, or don't contain "ab 2"; this results in all elements being matched.
Instead, just use;
li:not(:first-child):not(:contains('ab 2')
... as your selector (http://jsfiddle/rrWky/)
$("li:gt(0):not(:contains('ab 2'))").css('color','red');
http://jsfiddle/fmhYN/
You can slightly modify the beginning of your selector to fit your needs.
$("#list").find("li:gt(0):not(:contains('ab 2'))")
DEMO
try this
$("#list").find("li:gt(0):not(:contains('ab 2'))").css('display', 'none');
Try changing your code to:
$("#list").find("li:not(:first-child)").filter("li:not(:contains('ab 2'))").each(function () {
var current = $(this);
current.css('display', 'none');
});
Here is a jsFiddle of the proposed answer.
You could also remove the filter and bine the two selectors, like this:
$("#list").find("li:not(:first-child):not(:contains('ab 2'))").each(function () {
var current = $(this);
current.css('display', 'none');
});
Here is a jsFiddle of the selectors being bined.