2012-04-09 7 views
-1

Ich war ein Menü heute machen, und ich auf diesem merkwürdigen Fall gestolpert, mit folgendem HTML:Wie Javascript "this" mehrere Selektorrückgaben von jquery behandelt?

<div id="list1"> 
    <ul> 
     <li>1</li> 
     <li>2 - Here is a Submenu 
      <ul> 
       <li>3</li> 
       <li>4</li> 
      </ul> 
     </li> 
    </ul> 
</div> 

Dann habe ich die folgenden js verwendet:

$('#list1 li').click(function(){ 
    $('.list-item').removeClass('list-item'); 
    $(this).addClass('list-item'); 
}); 

Als ich dies die Klasse tun würde nur auf die äußere <li> angewendet werden, aber ich wollte, dass es sowohl auf die Eltern und Kind LI s angewendet wird.

Jetzt ist meine Frage, wie kann ich mit diesem "Returns" umgehen, so dass ich die Klassen sowohl auf die Eltern und Kind LI s anwenden?

Wie behandelt js diese Art von Selektoren? Wird das Ereignis wirklich zweimal ausgeführt und die letzte Klasse entfernt, die festgelegt wurde?

+0

@amnotiam ich nur meinen Gedankengang unter Hinweis darauf war, habe ich den Punkt der Verwirrung – Jonathan

Antwort

4

Das Problem ist, dass $('#list1 li') beide Ebenen von li Tags innerhalb auswählen und einen Click-Handler auf beide anwenden können. Darüber hinaus ermöglichen Sie, dass sich der Klick so weit ausbreitet, dass er von mehr als nur dem Klick-Klick gesehen werden kann.

Wenn Sie nur die äußere Ebene möchten, sollten Sie direkte Kindspezifikationen wie diese verwenden. und das wird isolieren, was Click-Handler tatsächlich installiert ist:

$("#list > ul > li") 

Dies wird nur die oberste Ebene li-Tags erhalten. Und würde der ganze Code wie folgt aussehen:

$('#list1 > ul > li').click(function(){ 
    $('.list-item').removeClass('list-item'); 
    $(this).addClass('list-item'); 
}); 

Wenn Sie den removeClass Betrieb nur die anderen LI-Tags auf der gleichen Ebene isolieren wollen, nicht über das gesamte Dokument, dann können Sie so etwas wie folgt verwenden:

$('#list1 > ul > li').click(function(){ 
    $(this).addClass('list-item').siblings().removeClass('list-item'); 
}); 

Ihre Kommentare haben mich ein wenig verwirrt über diese LI-Tags, die Sie anklickbar möchten. Wenn Sie tatsächlich die untere Ebene sein klickbare wollen und dann die Listenelementklasse gelten sowohl für die, die angeklickt wurde und die Eltern LI, dann können Sie das wie folgt tun:

$('#list1 > ul > li > ul > li').click(function() { 
    $("#list1 .list-item").removeClass('list-item'); 
    $(this).parents("li").add(this).addClass('list-item'); 
    return(false); // stop event propagation 
}); 
+0

entfernt zu erarbeiten, Ihre Veranstaltung sprudeln, können Sie auch aufhören zu sprudeln, aber die Verwendung der direkten Kind Spezifikationen ist besser. –

+0

Sorry, das war ziemlich unklar, ich wollte sagen, dass der angegebene Code nur für die oberste Ebene funktionieren würde, aber ich wollte beide Ebenen haben die Klasse, behoben :) – Jonathan

+0

@jonathan - jetzt hast du mich total verwirrt. Welche LI-Tags möchten Sie anklickbar machen? Und wenn einmal geklickt wird, welche LI-Tags möchten Sie die list-item-Klasse haben und aus welcher Liste soll sie entfernt werden? – jfriend00

1

Unabhängig davon, ob jQuery gilt Eine Methode für ein Element in einer Liste von Elementen oder für alle Elemente hängt von der Methode ab.

.click() und .addClass() werden beide auf alle jQuery-Objekte in Ihrem Selektor angewendet. In Ihrem Fall wird ein Klick-Handler auf alle li Elemente in #list angewendet. $(this) gilt für die spezifische li, die angeklickt wurde.

jedoch haben Sie li Elemente verschachtelt, was bedeutet, dass mehrere Klick-Handler ausgelöst, wenn Sie auf einer inneren verschachtelten li klicken, sowohl die verschachtelte li und es ist Eltern li.

Um dieses Ereignis Ausbreitung durch den DOM-Baum zu verhindern, setzen Sie einen stopPropagation() -Aufruf in Ihrem Click-Handler:

$('#list1 li').click(function(e){ 
    e.stopPropagation(); 

    $('.list-item').removeClass('list-item'); 
    $(this).addClass('list-item'); 
}); 

Sie können auch return false von Ihrem Handler, die Ausbreitung stoppt und verhindert, dass das Mahnverfahren. Dies ist spezifisch für jQuery.

+0

Vielen Dank für die stopPropagation(), ich habe es noch nie zuvor benutzt und es hat mir nur eine Menge Kopfschmerzen erspart. – RachelC

0

, wenn Sie einen „aktuellen“ Seitenstil hinzufügen:

$('#list1 > ul > li').on('click',function(){ 
    $(this).addClass('list-item') //adds class to clicked item 
     .siblings()     //find the others of the same level 
     .removeClass('list-item'); //remove their styles 
});