2010-07-27 7 views
2

J'ai une liste dans les listes. Lorsqu'un utilisateur clique sur un élément de liste (<li>), je souhaite que le <ul> imbriqué s'affiche. Avant de commencer à ajouter les listes imbriquées, je l'avais juste en cliquant sur un élément de la liste pour exécuter une fonction. Maintenant, en cliquant sur l'une des listes imbriquées exécute également cette fonction. Ce qui est logique, car ils font partie de l'élément de la liste. Outre un <span> enveloppant un <span> autour de la première partie de l'élément de liste et exécutant la fonction, y a-t-il un sélecteur qui me permettra d'exécuter quelque chose sur le parent <li> mais pas ses enfants, en particulier pas les listes enfants et liste des articles?jQuery cliquez sur li avec nested ul

HTML:

<ul class="buckets">   
    <li class="bucket"> 
     <img src="arrow_group_collapsed_true.png" class="arrow"> 
     <img src="blue_folder.png" class="folder"> 
     View all 
    </li> 

    <li class="bucket"> 
     <img src="arrow_group_collapsed_false.png" class="arrow"> 
     <img src="blue_folder.png" class="folder"> 
     Groups 
     <ul style="display: block;"> 
      <li id="group_id_15036" class="group_bucket"> 
       <img src="arrow_group_collapsed_true.png" class="arrow"> 
       <img src="blue_folder.png" class="folder"> 
       Group 1 
      </li> 
      <li id="group_id_14910" class="group_bucket"> 
       <img src="arrow_group_collapsed_true.png" class="arrow"> 
       <img src="blue_folder.png" class="folder"> 
       Group 2 
      </li> 
     </ul> 
    </li> 
</ul> 

Javascript (pas beaucoup, je peux montrer plus si nécessaire):

$('li.bucket').live('click', 
    function() 
    { 
     // do stuff 
    }) 

Je veux un clic sur "Groupes" ou "Voir tous les" pour exécuter la fonction de clic, mais un clic sur "Groupe 1" ou "Groupe 2" ne devrait pas.

Répondre

11

Il y a une façon officielle, mais dans votre cas, il pourrait être assez cher:

$('li.bucket *').live('click', function(event) { event.stopPropagation() }); 

Les enfants de auront maintenant un gestionnaire qui arrête l'événement de se propager vers le haut et le déclenchement des li 'li s gestionnaire. Essayez-le et voyez si l'application n'est pas trop ralentie.

+0

Donc, si un utilisateur clique sur quelque chose comme 'li.bucket li', que se passerait-il ici? – hookedonwinter

+0

Rien. N'est-ce pas le comportement voulu? – MvanGeest

+0

Ya, je voulais juste m'assurer. Puis-je remplacer cela? Je veux que les choses se passent quand je clique sur les liens les plus profonds, je ne veux pas non plus que la fonction se déclenche sur le haut. Si ça a du sens. – hookedonwinter

2

vous pouvez contrôler la fonction ci-dessus onmouseover l'élément de la liste & retirer onmouseout cas de l'élément. Mais je ne sais pas à quel point ce serait contre d'autres moyens.

+0

Bonne idée. MvanGeest a fonctionné, mais la bonne pensée :) – hookedonwinter

+0

Hehe réellement ces idées viennent quand je suis trop paresseux pour écrire un code de jQuery ... assez facile d'aider des personnes en leur donnant juste l'idée que le code: p – loxxy

1

J'aime la solution de @ MvanGeest mais il y a une meilleure façon de comprendre la propagation d'un événement. Quand un élément est cliqué, les éléments contenus obtiennent l'événement en premier et traversent l'arbre. Si je comprends votre requête, vous souhaitez empêcher l'envoi d'événements contenus dans l'arborescence. Je pense que le visuel est le meilleur.

<ul> 
    <li></li> 
    <li onclick="ShowChildUL()"> 
    <ul onclick="function(event) { event.stopPropagation() }"> 
     <li onclick="DoSomethingFun()"></li> 
     <li></li> 
     </ul> 
    </li> 
</ul> 

Dans ce cas, vous verrez que les onclick sur ul au milieu arrêtera la propagation jusqu'à la li. De plus, event.stopPropagation() n'est pas un navigateur croisé. Je recommande cette méthode comme votre fonction onclick.

function StopPropagation(e) { 
    var event = e || window.event; 

    [body of event handler function goes here] 

    if (event.stopPropagation) { 
    event.stopPropagation(); 
    } else { 
    event.cancelBubble = true; 
    } 
} 
Questions connexes