2010-10-28 16 views
28

Okay, ho voci di elenco, alcune hanno un intervallo, altre no.
Nel mio evento voglio aggiungere lo span quando non ne hanno ancora.jquery filtering ha + no

has() funziona bene, ma not() aggiunge lo span a entrambi ??

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>'); 
    })  
}) 
+0

Vedi anche http://stackoverflow.com/questions/2624832/jquery-selector-for-div-which- does-not-contain-img – goodeye

risposta

72

È possibile utilizzare una combinazione dei :not e :has selettori come questo

$("a.add-span").click(function() { 
    $("li:not(:has(span))").each(function(index) { 
     $(this).append('<span class="spn">new span<\/span>'); 
    }); 
}); 

Ecco una demohttp://www.jsfiddle.net/xU6fV/

+0

@FFish ... Questa è una soluzione più pulita –

+2

yup +1 lì :) – Sarfraz

+0

Bella combinazione di non e ha, alla fine scelgo l'opzione Sarfraz perché ho un altro filtro in ogni ciclo, Grazie! – FFish

2
$("a.add-span").click(function() { 
    $("li").each(function(index) { 
     if ($(this).children('span').length === 0){ 
     $(this).append('<span class="spn">new span<\/span>'); 
     } 
    })  
}) 

Con children() metodo, la proprietà length viene utilizzata per verificare se un span già esce e se non lo fa, uno è aggiunto/aggiunto.

Ulteriori informazioni:

+0

Non intendevi 'if ($ (this) .children ('span') ...'? Altrimenti, +1. Non pensavo nemmeno a quel metodo. =) –

+0

@Jeff Rupert: È vero, sono "bambini", non mi sono concentrato sul suo selezionatore. Grazie – Sarfraz

+0

@Sarfraz ... sarebbe più semplice specificare nel selettore per ogni funzione ... IE $ ("li: not (: has (span))"). Each (...) –

1

La risposta accettata funziona bene, se non si desidera filtrare solo gli elementi che hanno la span s come figli diretti.

Come il :has() e il ciclo .has() su tutti i discendenti, non solo i bambini.

In tal caso, è necessario utilizzare una funzione

$("li").not(function() { 
    // returns true for those elements with at least one span as child element 
    return $(this).children('span').length > 0 
}).each(function() { /* ... */ }) 
0

Prova questo,

$("a.add-span").click(function() { 
    $("li:not(:has(span))").each(function(index) { 
     $(this).append($("<span class='spn'>").html("Newly Added Span")); 
    }); 
}); 
0

Questo è il primo anello su Google durante la ricerca "jquery non ha". Lo scenario specifico che dovevo risolvere era leggermente diverso da questo. Ho dovuto aggiungere gli elementi not che hanno uno specifico elemento DOM, non semplicemente basati su un tag. Ciò significava che non potevo usare un selettore che utilizzava ciascuna soluzione sopra.

jQuery's has() tuttavia accetta un elemento DOM! Così ho creato un plugin jQuery per combinare queste due funzioni integrate.

Ho voluto condividerlo qui perché spero che possa aiutare anche gli altri nella mia situazione. Risponde anche alla domanda originale.

il plugin:

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

Implementazione:

$("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/


mi è stato inizialmente l'intenzione di trovare una funzione jQuery che avrebbe funzionato come addBack() ma utilizzando not invece. Se hai bisogno di qualcosa di così complicato, non esitare a utilizzare il seguente plug-in.

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

Con questo, la risposta sarebbe:

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

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

Problemi correlati