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; });
Randy L.
quelle

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');
Samjudson
quelle
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.

MacAnthony
quelle
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.

Ghayes
quelle
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

Mnebuerquo
quelle
32

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

$("#myimage").unbind("click");
John Boker
quelle
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)
dwhittenburg
quelle
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.

});​

quelle
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.

Davaus
quelle
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" );

alexpls
quelle
8

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

Shahrukh Azeem
quelle
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...

Akash
quelle
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
}
jquery_user
quelle
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")
Ilia Rostovtsev
quelle
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");
ow3n
quelle
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'))

Ishan Liyanage
quelle
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
Silviu Preda
quelle
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.

Kai Noack
quelle
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>

mysticmo
quelle
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();
});
Mitra
quelle