2010-10-28 5 views
28

Okay J'ai des éléments de liste, certains ont une portée, d'autres non.
Lors de mon événement, je souhaite ajouter l'intervalle quand ils n'en ont pas encore. Fonctionne bien, mais not() ajoute l'envergure à la fois ??Filtrage jquery a + pas

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

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

Répondre

72

Vous pouvez utiliser une combinaison des :not et :has sélecteurs comme celui-ci

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

Voici une La réponse acceptée fonctionne bien demohttp://www.jsfiddle.net/xU6fV/

+0

@FFish ... Ceci est une solution plus propre –

+2

yup +1 là :) – Sarfraz

+0

Belle combinaison de pas et a, à la fin je choisis l'option Sarfraz parce que j'ai un autre filtre dans chaque boucle, Merci! – 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>'); 
     } 
    })  
}) 

Avec la méthode children(), la length propriété est utilisée pour vérifier si oui ou non un span sort déjà et si elle ne le fait pas, un est ajouté/ajouté.

Plus d'info:

+0

N'avez-vous pas voulu dire 'if ($ (this) .children (' span ') ... '? Mais sinon, +1 ne pensait même pas à cette méthode. =) –

+0

@Jeff Rupert: Vrai, c'est "enfants", je ne me suis pas concentré sur son sélecteur. Merci – Sarfraz

+0

@Sarfraz ... il serait plus facile de simplement spécifier dans le sélecteur pour chaque fonction ... IE $ ("li: non (: a (span))").) (...) –

1

, si vous ne voulez pas filtrer uniquement les éléments qui ont le span s les enfants directs.

En tant que :has() et la boucle .has() sur tous les descendants, pas seulement les enfants.

Dans ce cas, vous devez utiliser une fonction

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

Essayez ceci,

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

Ceci est le premier lien sur Google lors de la recherche "jquery a non". Le scénario spécifique que je devais résoudre était un peu différent de celui-ci. Je devais not articles qui ont un élément DOM spécifique, pas simplement basé sur une étiquette. Cela signifiait que je ne pouvais pas utiliser un sélecteur que chaque solution ci-dessus utilisé. Cependant, le has() de jQuery accepte un élément DOM! J'ai donc créé un plugin jQuery pour combiner ces deux fonctions intégrées. Je voulais le partager ici parce que j'espère que cela aidera aussi les autres dans ma situation. Il répond également à la question initiale.

Le plug-in:

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

Mise en œuvre:

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


Je comptais d'abord trouver une fonction jQuery qui fonctionnerait comme addBack() mais en utilisant not à la place. Si vous avez besoin de quelque chose d'aussi compliqué, n'hésitez pas à utiliser le plugin suivant.

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

Avec cela, la réponse serait:

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

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