2012-04-05 7 views
0

Ich versuche, einen $('body').live('click') Listener hinzuzufügen, nachdem der Benutzer auf ein div geklickt hat. Der Zweck besteht darin, eine benutzerdefinierte Dropdown-Box zu erstellen, die der Benutzer öffnen und schließlich schließen kann, indem er auf eine beliebige Stelle auf der Seite klickt.Die Verwendung von .live ('click') innerhalb einer .click() - Funktion löst sich aus

Aber wenn ich hinzufügen .live() oder .bind() Funktion innerhalb einer .click() Funktion, die live() Funktion aus irgendeinem Grund ausgelöst:

$('#myDiv').click(function(){ 
    $('#myDiv .child').show().addClass('showing'); 
    $('body').live('click', function(){ 
      $('#myDiv .child').hide(); 
      $('body').die(); 
    }) 
}) 

#myDiv gezeigt wird, aber sofort versteckt, belegt durch die anhalt .showing Klasse.

Bin ich mit live() falsch? Wie vermeide ich diese Rekursion?

+0

erklären, was Sie eher versuchen zu tun, als zu erklären, was Sie gerade tun Darüber hinaus können Sie .one() für einen einmaligen Ereignishandler verwenden. Vielleicht können wir eine Alternative anbieten, anstatt einen möglicherweise fehlerhaften Code zu reparieren. – Joseph

Antwort

3

return false Ereignispropagierung stoppen:

$('#myDiv').click(function(){ 
    $('#myDiv .child').show().addClass('showing'); 
    $('body').live('click', function(){ 
      $('#myDiv .child').hide(); 
      $('body').die(); 
    }); 
    return false; 
}) 
+0

Danke, das hat auch funktioniert und es ist ein bisschen einfacher als ein Ereignis zu übergeben und event.stopPropagation() zu verwenden. – podcastfan88

+0

Immer willkommen :-) –

+2

@stuart - FYI, die Rückkehr 'false' ist nicht genau das gleiche' e.stopPropagation() '. Die Rückgabe von false bewirkt, dass jQuery sowohl "e.stopPropagation()" als auch "e.preventDefault()" ausführt. Vielleicht macht es dir in diesem Fall nicht anders, aber du solltest verstehen, dass es nicht genau dasselbe ist. Soweit das Ereignis an den Event-Handler übergeben wird, wird es immer an einen Event-Handler übergeben, egal ob Sie das Argument deklarieren oder nicht - es ist immer da. – jfriend00

0

Verwenden zweite Körper klicken Bindung ohne Live (Sie auch brauchen es nicht, denn es ist immer auf der Seite) und die Verwendung Timeout:

$('#myDiv').on('click',function(){ 
    $('#myDiv .child').show().addClass('showing'); 
setTimeout(function(){ 
$('body').on('click', function(){ 
      $('#myDiv .child').hide(); 
      $('body').off('click'); 
    }); 
},0); 

}); 
+0

Meine Tests zeigen, dass dies immer noch selbst auslöst: http://jsfiddle.net/GsP5j/1/. Ich habe 'live()' verwendet, weil ich '$ ('body')' nicht immer Klickereignisse akzeptieren möchte. – podcastfan88

+0

Bitte überprüfen Sie die Variante mit Timeout – Rustam

+0

Das hat funktioniert, danke für die Option. – podcastfan88

0

Vielleicht sollte es funktionieren, vielleicht sollte es nicht. Aber das tut es nicht. Ich würde empfehlen, alle Event-Handler am Anfang einzurichten und nur eine globale Variable (z. B.) zu haben, die verfolgt, ob der zweite Event-Handler tatsächlich antworten sollte oder nicht.

0

Wahrscheinlich müssen Sie die Übertragung des aktuellen Ereignisses stoppen, damit es nicht bis zum Hauptteil der Nachricht gesprudelt wird, wo es von Ihrem neuen Ereignishandler angezeigt wird.

$('#myDiv').on('click',function(e){ 
    $('#myDiv .child').show().addClass('showing'); 
    e.stopPropagation(); 
    $(document.body).one('click', function() { 
      $('#myDiv .child').hide(); 
    }); 
}) 
+0

Danke, das hat funktioniert! Ich habe von Fortpflanzung gehört, musste sich aber vorher nie darum kümmern. – podcastfan88