Der beste Weg, um einen Event-Handler in jQuery zu entfernen?


1053

Ich habe eine input type="image". Dies verhält sich wie die Zellennotizen in Microsoft Excel. Wenn jemand eine Nummer in das Textfeld eingibt, mit dem dies input-imagegepaart ist, richte ich einen Ereignishandler für das ein input-image. Wenn der Benutzer dann auf klickt image, wird ein kleines Popup angezeigt, in dem er den Daten einige Notizen hinzufügen kann.

Mein Problem ist, dass ich den input-imageEreignishandler des Benutzers deaktivieren muss, wenn ein Benutzer eine Null in das Textfeld eingibt . Ich habe folgendes versucht, aber ohne Erfolg.

$('#myimage').click(function { return false; });

Antworten:


1626

jQuery ≥ 1,7

Ab jQuery 1.7 wurde die Ereignis-API aktualisiert. .bind()/ Sind aus Gründen der .unbind()Abwärtskompatibilität weiterhin verfügbar. Die bevorzugte Methode ist jedoch die Verwendung der Funktionen on () / off () . Das Folgende wäre jetzt,

$('#myimage').click(function() { return false; }); // Adds another click event
$('#myimage').off('click');
$('#myimage').on('click.mynamespace', function() { /* Do stuff */ });
$('#myimage').off('click.mynamespace');

jQuery <1.7

In Ihrem Beispielcode fügen Sie dem Bild einfach ein weiteres Klickereignis hinzu, ohne das vorherige zu überschreiben:

$('#myimage').click(function() { return false; }); // Adds another click event

Beide Klickereignisse werden dann ausgelöst.

Wie bereits erwähnt, können Sie mit "Unbind" alle Klickereignisse entfernen:

$('#myimage').unbind('click');

Wenn Sie ein einzelnes Ereignis hinzufügen und dann entfernen möchten (ohne andere hinzugefügte Ereignisse zu entfernen), können Sie den Ereignis-Namespace verwenden:

$('#myimage').bind('click.mynamespace', function() { /* Do stuff */ });

und um nur Ihre Veranstaltung zu entfernen:

$('#myimage').unbind('click.mynamespace');

6
Gibt es eine Möglichkeit zu testen, ob unbind()es funktioniert? Ich habe es hinzugefügt und beide Ereignisse werden immer noch ausgelöst.
David Yell

19
Nun, wenn beide Ereignisse immer noch ausgelöst werden, funktioniert es offensichtlich nicht. Sie müssten mehr Informationen geben, um eine richtige Antwort zu erhalten. Versuchen Sie, eine separate Frage zu stellen.
Samjudson

13
Alte Antwort - auch wie die enthaltenen Namespace-Informationen - aber ich vergesse; Gibt on / off das jQ-Objekt zurück? Wenn ja, wäre eine vollständigere Antwort vielleicht auf Daisy Chain:$('#myimage').off('click').on('click',function(){...})
Vol7ron

3
Ja, also ja, wenn Sie alle anderen Klickereignisse löschen und dann Ihre eigenen hinzufügen möchten, können Sie den oben verketteten Anruf ausführen.
Samjudson

Die Verwendung .unbind()hat mir in einer Situation geholfen, in der ich eine Reihe von Kontrollkästchen umgeschaltet habe, aber ich habe den .click()Handler wiederholt neu hinzugefügt , wodurch die App hängen blieb.
TecBrat

63

Dies war nicht verfügbar, als diese Frage beantwortet wurde, aber Sie können auch die live () -Methode verwenden, um Ereignisse zu aktivieren / deaktivieren.

$('#myimage:not(.disabled)').live('click', myclickevent);

$('#mydisablebutton').click( function () { $('#myimage').addClass('disabled'); });

Mit diesem Code wird beim Klicken auf #mydisablebutton die deaktivierte Klasse zum Element #myimage hinzugefügt. Dadurch wird festgelegt, dass der Selektor nicht mehr mit dem Element übereinstimmt und das Ereignis erst ausgelöst wird, wenn die Klasse 'disabled' entfernt wurde, wodurch der Selektor .live () wieder gültig wird.

Dies hat weitere Vorteile, da das Styling auch auf dieser Klasse basiert.


3
Gute Art zu verwenden live(), noch nie darüber nachgedacht, es so zu verwenden ... Abgesehen von der Bequemlichkeit der Codierung, ist es schneller oder bietet es andere Vorteile für die Verwendung von Binden / Entbinden?
Chakrit

2
Wenn Sie Elemente hinzufügen / entfernen, gibt es bestimmte Leistungsvorteile gegenüber dem Binden, da das Binden mit Live nur einmal durchgeführt wird. jQuery scheint sich eher auf Live- und Delegierungsereignisse zu konzentrieren, als an bestimmte Elemente zu binden.
MacAnthony

3
Um Live zu deaktivieren, können Sie die ()
Moons

9
"Ab jQuery 1.7 ist die .live () -Methode veraltet. Verwenden Sie .on (), um Ereignishandler anzuhängen. Benutzer älterer Versionen von jQuery sollten .delegate () anstelle von .live () verwenden." api.jquery.com/live
Lucas Pottersky

12
Ah, launisch jQuery, an einem Tag bringst du einem Mann 300 Wiederholungen, am nächsten Tag ist es veraltet.
MrBoJangles

37

Wenn Sie nur einmal auf ein Ereignis reagieren möchten , sollte die folgende Syntax sehr hilfreich sein:

 $('.myLink').bind('click', function() {
   //do some things

   $(this).unbind('click', arguments.callee); //unbind *just this handler*
 });

Mithilfe von argument.callee können wir sicherstellen, dass der eine bestimmte Handler für anonyme Funktionen entfernt wird, und somit einen einzelnen Zeithandler für ein bestimmtes Ereignis haben. Hoffe das hilft anderen.


2
Absolut, obwohl Sie manchmal eine bestimmte Logik darüber haben möchten, wann der Handler ungebunden sein sollte (z. B. nicht binden, es sei denn, sie haben zuerst ein Textfeld ausgefüllt).
Ghayes

5
Argumente.Callee ist im strengen Modus veraltet!
Zloctb

37

Dies kann mithilfe der Funktion zum Aufheben der Bindung erfolgen.

$('#myimage').unbind('click');

In jquery können Sie demselben Objekt und Ereignis mehrere Ereignishandler hinzufügen. Dies bedeutet, dass das Hinzufügen eines neuen nicht das alte ersetzt.

Es gibt verschiedene Strategien zum Ändern von Ereignishandlern, z. B. Ereignis-Namespaces. Es gibt einige Seiten dazu in den Online-Dokumenten.

Schauen Sie sich diese Frage an (so habe ich von Unbind erfahren). In den Antworten finden Sie einige nützliche Beschreibungen dieser Strategien.

Lesen von gebundenen Hover-Rückruffunktionen in jquery


32

Vielleicht funktioniert die Methode zum Aufheben der Bindung für Sie

$("#myimage").unbind("click");

30

Ich musste das Ereignis mit der Requisite und dem attr auf null setzen. Ich konnte es mit dem einen oder anderen nicht machen. Ich konnte auch .unbind nicht zur Arbeit bringen. Ich arbeite an einem TD-Element.

.prop("onclick", null).attr("onclick", null)

1
Ich habe dafür gestimmt, weil ich versucht habe, eine Unschärfe für ungefähr 30 Minuten zu lösen. '.unbind' hat nicht funktioniert, '.prop' hat nicht funktioniert, '.attr' hat nicht funktioniert, aber dieser Trick mit .prop und .attr zusammen hat den Trick gemacht. seltsam. Ich benutze Chrome mit jquery 1.7.2
Jeremy

Hier gilt das gleiche! Ich habe versucht, das Klickereignis aus dem einfachen <a> -Tag zu entfernen! Danke dafür. In meinem Fall war .prop ("onclick", null) genug.
Jan Lobau

hier gilt das gleiche. Unbind and Off hat bei FF mit jq 1.7.2 nicht funktioniert und .prop ("onclick", null) war auch in meinem Fall ausreichend
bryanallott

4
Ich denke, der Grund, warum die oben genannten Methoden für euch nicht funktioniert haben, ist, wie ihr sie eingerichtet habt. Wenn Sie den Ereignishandler in das DOM geschrieben haben, ist das Löschen dieses Attributs erforderlich, um den Ereignishandler zu löschen. Ich denke jedoch, dass die meisten Personen (einschließlich ich) solche Dinge (Javascrip, Ereignishandler usw.) aus dem DOM heraushalten möchten DOM, wenn wir also einen Ereignishandler einrichten möchten, verwenden wir so etwas $("#elementId").click(function(){//Event execution code goes here});, dass es überhaupt nicht auf der HTML-Seite ist. Um zu verdeutlichen, dass wir tatsächlich verwenden müssen .unbind(), oder das bevorzugte.off()
VoidKing

Hier ist ein Beispiel von jemandem, der gerade eine Stunde damit verbracht hat, herauszufinden, dass über jQuery hinzugefügte Eigenschaften nicht im Elementfenster von Chrome angezeigt werden. Ich habe es versucht unbindund offes hat das Problem nicht gelöst. Vielen Dank!
Renan

13

Wenn das Ereignis auf diese Weise angehängt ist und das Ziel nicht verbunden werden soll:

$('#container').on('click','span',function(eo){
    alert(1);

    $(this).off(); //seams easy, but does not work

    $('#container').off('click','span'); //clears click event for every span

    $(this).on("click",function(){return false;}); //this works.

});​

11

Möglicherweise fügen Sie den onclickHandler als Inline-Markup hinzu:

<input id="addreport" type="button" value="Add New Report" onclick="openAdd()" />

Wenn ja, funktioniert die Abfrage .off()oder .unbind()nicht. Sie müssen den ursprünglichen Ereignishandler auch in jquery hinzufügen:

$("#addreport").on("click", "", function (e) {
   openAdd();
});

Dann hat die Abfrage einen Verweis auf den Ereignishandler und kann ihn entfernen:

$("#addreport").off("click")

VoidKing erwähnt dies in einem Kommentar oben etwas schräger.


9

Aktualisiert für 2014

Mit der neuesten Version von jQuery können Sie jetzt alle Ereignisse in einem Namespace durch einfaches Ausführen aufheben $( "#foo" ).off( ".myNamespace" );


8

Der beste Weg, um ein Inline-Onclick-Ereignis zu entfernen, ist $(element).prop('onclick', null);


8

Für remove ALLE event-handlers hat das bei mir funktioniert:

Alle Event-Handler zu entfernen bedeutet, die Ebene HTML structureohne alle event handlersan das elementund sein angehängten zu haben child nodes. Dazu hat jQuery's clone()geholfen.

var original, clone;
// element with id my-div and its child nodes have some event-handlers
original = $('#my-div');
clone = original.clone();
//
original.replaceWith(clone);

Damit haben wir das cloneanstelle des originalohne event-handlers.

Viel Glück...


7

Danke für die Auskunft. Sehr hilfreich Ich habe es verwendet, um die Seiteninteraktion im Bearbeitungsmodus eines anderen Benutzers zu sperren. Ich habe es in Verbindung mit ajaxComplete verwendet. Nicht unbedingt das gleiche Verhalten, aber etwas ähnlich.

function userPageLock(){
    $("body").bind("ajaxComplete.lockpage", function(){
        $("body").unbind("ajaxComplete.lockpage");
        executePageLock();      
    });
};  

function executePageLock(){
    //do something
}

5

Falls .on()zuvor die Methode mit einem bestimmten Selektor verwendet wurde, wie im folgenden Beispiel:

$('body').on('click', '.dynamicTarget', function () {
    // Code goes here
});

Beide unbind()und .off()Methoden werden nicht funktionieren.

Die .undelegate () -Methode kann jedoch verwendet werden, um den Handler für alle Elemente, die mit dem aktuellen Selektor übereinstimmen, vollständig aus dem Ereignis zu entfernen:

$("body").undelegate(".dynamicTarget", "click")

1
Ich habe die ganze Seite gescrollt, während ich nach dieser Lösung gesucht habe, die wie ein Zauber funktioniert hat.
Abhishek Pandey

4

Wenn Sie $(document).on()einem dynamisch erstellten Element einen Listener hinzufügen, müssen Sie möglicherweise Folgendes verwenden, um es zu entfernen:

// add the listener
$(document).on('click','.element',function(){
    // stuff
});

// remove the listener
$(document).off("click", ".element");


2

Wenn Sie die onclickVia einstellen html, müssen SieremoveAttr ($(this).removeAttr('onclick'))

Wenn Sie es über jquery einstellen (wie nach dem ersten Klick in meinen obigen Beispielen), müssen Sie dies tun unbind($(this).unbind('click'))


2

Ich weiß, dass dies zu spät kommt, aber warum nicht einfaches JS verwenden, um das Ereignis zu entfernen?

var myElement = document.getElementById("your_ID");
myElement.onclick = null;

oder, wenn Sie eine benannte Funktion als Ereignishandler verwenden:

function eh(event){...}
var myElement = document.getElementById("your_ID");
myElement.addEventListener("click",eh); // add event handler
myElement.removeEventListener("click",eh); //remove it

Guter Vorschlag, ich bevorzuge die Verwendung von nativem Javascript, wenn verfügbar
Michiel

1

Alle beschriebenen Ansätze haben bei mir nicht funktioniert, da ich das Klickereignis mit on()zu dem Dokument hinzugefügt habe, in dem das Element zur Laufzeit erstellt wurde:

$(document).on("click", ".button", function() {
    doSomething();
});


Meine Problemumgehung:

Da ich die ".button" -Klasse nicht aufheben konnte, habe ich der Schaltfläche mit denselben CSS-Stilen einfach eine andere Klasse zugewiesen. Auf diese Weise ignorierte der Live- / On-Event-Handler den Klick endgültig:

// prevent another click on the button by assigning another class
$(".button").attr("class","buttonOff");

Ich hoffe, das hilft.


1

Hoffe mein unten stehender Code erklärt alles. HTML:

(function($){

     $("#btn_add").on("click",function(){
       $("#btn_click").on("click",added_handler);
       alert("Added new handler to button 1");
     });

  
 
     $("#btn_remove").on("click",function(){
       $("#btn_click").off("click",added_handler);
       alert("Removed new handler to button 1");
     });

  
   function fixed_handler(){
    alert("Fixed handler");
  }
  
   function added_handler(){
    alert("new handler");
  }
  
  $("#btn_click").on("click",fixed_handler);
  $("#btn_fixed").on("click",fixed_handler);
  
  
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn_click">Button 1</button>
  <button id="btn_add">Add Handler</button>
  <button id="btn_remove">Remove Handler</button>
  <button id="btn_fixed">Fixed Handler</button>


1
Warum gehen Sie })(jQuery);in das IIFE über, wenn bereits global darauf zugegriffen werden kann?
Bryan P

2
Gute Frage Bryan. Diese Methode wurde aus praktischen Gründen in mein Gen eingegeben. - Es kann eine Möglichkeit für Nicht-JQuery-Plugins geben, die Variable $ zu haben, daher kann ich $ nicht direkt verwenden. - Die häufige Verwendung des Wortes "jQuery" in einer js-Skriptdatei kann die Bytegröße der Datei erhöhen, wobei jQuery eine 6-Byte-Zeichenfolge ist. Daher bevorzuge ich "$" oder eine beliebige Variable eines einzelnen Bytes.
Mysticmo

0

Entfernen Sie das einfach von der Schaltfläche:

$('.classname').click(function(){
$( ".classname" ).remove();
});
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.