jquery filtering has + not

Viewed 43587

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>');
    })    
})
5 Answers

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:

(function ( $ ) {
    $.fn.extend({
        not_has: function (param) {
            return this.not(this.has(param));
        }
    });
}( jQuery ));

Implementation:

$("a.add-span").click(function() {
    $("li").not_has("span")
    .append('<span class="spn">new span<\/span>');

    // Prevent the page from navigating away
    return false;
});

https://jsfiddle.net/brjkg10n/1/


I was initially intending to find a jQuery function that would work like addBack() but using not instead. If you need something so complicated, then please feel free to use the following plugin.

(function ( $ ) {
    $.fn.extend({
        notBack: function () {
            return this.prevObject.not(this);
        }
    });
}( jQuery ));

With this, the answer would be:

$("li").has("span").notBack()
.append('<span class="spn">new span<\/span>');

https://jsfiddle.net/2g08gjj8/1/

Related