Okay I have list items, some have a span, some not.
On my event I want to add the span when they don't have any yet.
has()
works fine, but not()
adds the span to both??
HTML:
<ul>
<li>
<p>item</p>
<span class="spn">empty span</span>
</li>
<li>
<p>item 2</p>
</li>
<ul>
<hr>
<a class="add-span"href="#">check</a>
JS:
$("a.add-span").click(function() {
$("li").each(function(index) {
// $(this).has("span").find("span").append(" - appended");
$(this).not("span").append('<span class="spn">new span<\/span>');
})
})
The accepted answer works well, if you don't want to filter out only those elements which do have the
span
s as direct children.As the
:has()
and the.has()
loop over all descendants, not just the children.In that case, you have to use a function
This is the first link on Google when searching "jquery not has". The specific scenario I needed to solve was a little different to this one. I had to
not
items that have a specific DOM element, not simply based on a tag. This meant I couldn't use a selector which each solution above used.jQuery's
has()
however does accept a DOM element! So I created a jQuery plugin to combine these two inbuilt functions.I wanted to share it here because hopefully it will help others in my situation too. It also answers the original question.
The Plugin:
Implementation:
https://jsfiddle.net/brjkg10n/1/
I was initially intending to find a jQuery function that would work like
addBack()
but usingnot
instead. If you need something so complicated, then please feel free to use the following plugin.With this, the answer would be:
https://jsfiddle.net/2g08gjj8/1/
Try this,
With
children()
method, thelength
property is used to check whether or not aspan
already exits and if it doesn't, one is added/appended.More Info:
You can use a combination of the :not and :has selectors like this
Here is a demo http://www.jsfiddle.net/xU6fV/