2013-06-13 8 views
5

Ich habe 2 Tasten, klicken Sie auf eine wird Klassen für beide Tasten tauschen.
Die Klassen sind selected und unselected.Mit jQuery zum Entfernen und Hinzufügen von Klassen zu Schaltflächen, die neue Klasse hinzugefügt wird nicht funktionieren mit der Klick-Funktion

Mein CodePen:
http://codepen.io/leongaban/pen/iLBvs

enter image description here

Zum Beispiel: Klicken Sie auf die Schaltfläche Login entfernen wird es nicht ausgewählte Klasse ist und ihm seine ausgewählte Klasse geben und dem Register, um in dem nicht ausgewählte Klasse geben.

Jetzt ist das Problem, dass die register_unselected Klasse nicht funktioniert. Die unselected Klassen sind diejenigen, die Klicks Aktionen in meinem jQuery haben.

Ich sollte in der Lage sein, auf den grauen Knopf zu klicken und ihn blau zu drehen. Nach dem Klicken auf die erste graue Schaltfläche (Login) funktioniert das neue graue Tastenregister jedoch nicht.

Mit dem Inspektor von Chrome kann ich deutlich sehen, dass meine Klasse register_unselected hinzugefügt wurde, aber die Klickfunktion funktioniert nicht.

enter image description here

Irgendwelche Ideen? Wie würdest du das angehen?

// Login Tab (default : first) 
$(".login_unselected").click(function(){ 

    console.log('clicked login'); 

    // Show Login Tab as selected 
    $(this) 
    .removeClass('login_unselected') 
    .addClass('login_selected'); 

    // Show Register Tab as unselected 
    $(this).parent().find('#tab_register') 
    .removeClass('register_selected') 
    .addClass('register_unselected'); 

}); 

// Register Tab 
$(".register_unselected").click(function(){ 

    console.log('clicked register'); 

    // Show Login Tab as selected 
    $(this) 
    .removeClass('register_unselected') 
    .addClass('register_selected'); 

    // Show Register Tab as unselected 
    $(this).parent().find('#tab_login') 
    .removeClass('login_selected') 
    .addClass('login_unselected'); 

}); 
+2

zwei Wörter: 'event delegation', das click -Ereignis sucht nicht nach Elementen, die diese Klasse erhalten, wenn es bindet, nur Elemente, die beim Laden der Seite mit dieser Klasse existieren. Die schnelle Lösung ist '$ (document) .on ('click', 'class', function() {// normaler Code});' beim Ersetzen von 'document' durch ein statisches Element, das sich nicht ändert. – Ohgodwhy

+0

Danke für den Tipp! : D –

+1

@Leon sehen meine derzeit nicht gefundene Lösung, verwenden Sie weniger als die Hälfte der Menge an Code, den Sie gerade verwenden. Keine Notwendigkeit dafür. – Dom

Antwort

8

Wenn Sie anrufen $(".register_unselected").click() jQuery tatsächlich das DOM für alle Elemente sucht .register_unselected passend und lauscht dann auf sie Click-Ereignisse. Da Ihr Element erst nach dem Aufruf dieser Methode existiert, hat dies keine Auswirkungen.

Verwenden Sie stattdessen $("body").on("click", ".register_unselected", function(){});

Sie können auch body durch einen anderen Selektor ersetzen, der immer das Element enthält, das die Klassen ändert.

EDIT: Hier ist ein Gabel CodePen: http://codepen.io/anon/pen/DqFuL

+0

Ah danke! Das macht Sinn :) 6 weitere Minuten! –

+1

Danke für deinen Code .. Es hat mir wirklich geholfen – Dibish

1

Wenn Sie die Klick-Handler basierend auf Klasse zuweisen, werden die Handler auf die Tasten gesetzt, der diese Klasse DAMALS entsprechen. Sie werden sich nicht ändern, nur weil Sie die Klassen geändert haben. Sie müssen einen Click-Handler implementieren, der erkennt, welche Klassen zum Zeitpunkt des Klickens eingestellt sind, und entsprechend handeln.

1

Verwenden Sie .on(), um die Klickereignisse von einem dom-Element zu delegieren, das statisch ist und beides enthält.

Also, wenn Sie auf Seite Last, Sie haben:

<ul id="container"> 
    <li class="login_selected">Login</li> 
    <li class="register_unselected">Register</li> 
</ul> 

Dann anstelle der Verwendung.() klicken, dies zu tun:

$('#container').on('click', '.login_unselected', function(){ 
    //do stuff 
}); 

und

$('#container').on('click', '.register_unselected', function(){ 
    //do stuff 
}); 
1

Sie können auch tun dies

// Login Tab (default : first) 
$(".login_unselected").click(function(){ 

    console.log('clicked login'); 

    // Show Login Tab as selected 
    $(this) 
    .removeClass('login_unselected') 
    .addClass('login_selected'); 

    // Show Register Tab as unselected 
    $(this).parent().find('#tab_register') 
    .removeClass('register_selected') 
    .addClass('register_unselected'); 

}); 
// Register Tab 

$("#tab_register").click(function(){ 

    console.log('clicked register'); 
    if($(this).hasClass("register_unselected")){ 
    // Show Login Tab as selected 
    $(this) 
    .removeClass('register_unselected') 
    .addClass('register_selected'); 

    // Show Register Tab as unselected 
    $(this).parent().find('#tab_login') 
    .removeClass('login_selected') 
    .addClass('login_unselected'); 
    } 
}); 

auf die ID anhören und dann prüfen, ist es diese Klasse ist.

.on ist schneller

[http://www.jsperf.com/change-class-on-click] 
2

niemand mehr auf der Hand und elegante Lösung gegeben hat.

Lässt die CSS aufzuräumen ein wenig:

//instead of .login_unselected, .registerunselected 
.target { 
     color: #ccc; 
     background: #666; 
     cursor: pointer; 
} 

//instead of .x_selected, .y_selected 
.selected { 
     color: #fff; 
     background: #3399cc; 
     text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); 
} 

So ist der HTML ist jetzt

<ul> 
    <li id="tab_login" class="target">Login</li> 
    <li id="tab_register" class="target">Register</li> 
</ul> 

Die jQuery ist:

$("ul").on("click", ".target", function(){ 

     // Remove selected class from any that have it 
     $(".target").removeClass('selected'); 
     // Add class to the one you're clicking on 
     $(this).addClass('selected'); 

}); 

Statt die Klasse der Aufruf .target können Sie nennen Sie es .unselected. Aus dem Kontext Ihrer Frage ist es wahrscheinlich, dass Sie nicht zwei separate Klassen benötigen, Klassen werden erstellt, um auf viele Elemente angewendet zu werden, und wenn Sie sie einzeln referenzieren müssen, haben Sie die id s bereits.

Denken Sie auch daran, dass Sie viele Klassen auf ein Element anwenden können und dann Stile von einer Klasse überschreiben können, indem Sie unterschiedliche Eigenschaftswerte für die letzte Klasse angeben. Welche Klasse zuletzt angewendet wird, überschreibt die Einstellungen von Klassen, die bereits angewendet wurden, es sei denn, Werte für die Eigenschaften, die überschrieben werden sollen, wurden in der übergeordneten Klasse nicht angegeben.

+0

Oh danke für das Codebeispiel :) Tatsächlich gibt es in meiner lokalen Umgebung verschiedene Hintergrundbilder (mit einem Schatten links oder rechts) für die nicht ausgewählten Tabs. Auch das text-align unterscheidet sich für das Login und das Register. –

+0

Sie könnten diese Stile stattdessen auf die IDs anwenden? – Dom

+0

aber wenn eine Registerkarte im ausgewählten Zustand ist, gibt es kein Hintergrundbild und einige Farben ändern sich, aber ich denke, ich könnte jQuery verwenden, um die CSS –