Najlepszy sposób na usunięcie modułu obsługi zdarzeń w jQuery?

1053

Mam input type="image". To działa jak notatki komórkowe w Microsoft Excel. Jeśli ktoś wpisze liczbę w pole tekstowe, z którym input-imagejest ona sparowana, skonfiguruję moduł obsługi zdarzeń dla input-image. Następnie, gdy użytkownik kliknie przycisk image, pojawi się małe okno podręczne, aby dodać notatki do danych.

Mój problem polega na tym, że gdy użytkownik wpisuje zero w polu tekstowym, muszę wyłączyć moduł input-imageobsługi zdarzeń. Próbowałem następujących, ale bezskutecznie.

$('#myimage').click(function { return false; });
Randy L.
źródło

Odpowiedzi:

1626

jQuery ≥ 1,7

Począwszy od jQuery 1.7 API zdarzeń zostało zaktualizowane, .bind()/ .unbind()są nadal dostępne dla kompatybilności wstecznej, ale preferowaną metodą jest użycie funkcji on () / off () . Poniżej byłoby teraz

$('#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

W przykładowym kodzie po prostu dodajesz kolejne zdarzenie kliknięcia do obrazu, nie zastępując poprzedniego:

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

Oba zdarzenia kliknięcia zostaną uruchomione.

Jak już powiedziano, możesz usunąć cofnięcie wszystkich zdarzeń związanych z kliknięciem:

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

Jeśli chcesz dodać pojedyncze zdarzenie, a następnie je usunąć (bez usuwania innych, które mogły zostać dodane), możesz użyć przestrzeni nazw zdarzeń:

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

i aby usunąć tylko swoje wydarzenie:

$('#myimage').unbind('click.mynamespace');
samjudson
źródło
6
Czy istnieje sposób na sprawdzenie, czy unbind()działa? Dodałem go i oba wydarzenia są nadal uruchamiane.
David Yell,
19
Cóż, jeśli oba zdarzenia nadal się uruchamiają, to oczywiście nie działa. Musisz podać więcej informacji, aby uzyskać właściwą odpowiedź. Spróbuj zadać osobne pytanie.
samjudson,
13
Stara odpowiedź - podobnie jak dołączona informacja o przestrzeni nazw - ale zapominam; czy włączenie / wyłączenie zwraca obiekt jQ? Jeśli tak, być może bardziej kompletną odpowiedzią byłoby połączenie łańcuchowe:$('#myimage').off('click').on('click',function(){...})
vol7ron 10.01.13
3
Tak, tak, więc tak, jeśli chcesz wyczyścić wszystkie inne zdarzenia kliknięcia, a następnie dodać własne, możesz wykonać powyższe połączenie powiązane.
samjudson
Używanie .unbind()pomogło mi w sytuacji, w której przełączałem kilka pól wyboru, ale po ponownym uruchomieniu .click()wielokrotnie dodawałem program obsługi, powodując zawieszenie się aplikacji.
TecBrat,
63

Nie było to dostępne, gdy udzielono odpowiedzi na to pytanie, ale można również użyć metody live () , aby włączyć / wyłączyć zdarzenia.

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

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

Z tym kodem stanie się to, że kliknięcie przycisku #mydisable spowoduje dodanie klasy wyłączonej do elementu #myimage. Sprawi to, że selektor nie będzie już pasował do elementu, a zdarzenie nie zostanie uruchomione, dopóki klasa „disabled” nie zostanie usunięta, dzięki czemu selektor .live () znów będzie ważny.

Ma to inne zalety, dodając również stylizację opartą na tej klasie.

MacAnthony
źródło
3
Fajny sposób użycia live(), nigdy wcześniej nie myślałem o używaniu go w ten sposób ... Czy oprócz wygody kodowania jest on szybszy, czy oferuje jakieś inne zalety korzystania z opcji bind / unbind?
chakrit
2
Jeśli dodajesz / usuwasz elementy, oznacza to wyraźną przewagę wydajności nad wiązaniem, ponieważ wiązanie za pomocą live jest wykonywane tylko raz. Wydaje się, że jQuery przenosi się do większej liczby wydarzeń na żywo i deleguje wydarzenia, a nie wiąże się z określonymi elementami.
MacAnthony
3
Aby wyłączyć transmisję na żywo, możesz użyć die ()
Księżyce
9
„Począwszy od jQuery 1.7, metoda .live () jest przestarzała. Użyj .on (), aby dołączyć procedury obsługi zdarzeń. Użytkownicy starszych wersji jQuery powinni używać .delegate () zamiast .live ().” api.jquery.com/live
Lucas
12
Ach, kapryśny jQuery, pewnego dnia przyniesiesz facetowi 300 powtórzeń, następnego dnia jest przestarzały.
MrBoJangles
37

Jeśli chcesz odpowiedzieć na zdarzenie tylko raz , poniższa składnia powinna być naprawdę pomocna:

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

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

Za pomocą arguments.callee możemy zagwarantować, że jeden konkretny moduł obsługi funkcji anonimowych zostanie usunięty, a tym samym mieć pojedynczy moduł obsługi czasu dla danego zdarzenia. Mam nadzieję, że to pomaga innym.

Ghayes
źródło
2
Oczywiście, chociaż czasami możesz chcieć mieć pewną logikę, kiedy program obsługi powinien być niezwiązany (np. Nie usuwaj powiązania, chyba że najpierw wypełnią pole tekstowe).
ghayes
5
arguments.callee jest zdeprasowany w trybie ścisłym!
zloctb
37

Można to zrobić za pomocą funkcji unbind.

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

Możesz dodać wiele procedur obsługi zdarzeń do tego samego obiektu i zdarzenia w jquery. Oznacza to, że dodanie nowego nie zastępuje starych.

Istnieje kilka strategii zmiany procedur obsługi zdarzeń, takich jak przestrzenie nazw zdarzeń. Dokumenty online zawierają kilka stron na ten temat.

Spójrz na to pytanie (tak nauczyłem się unbind). W odpowiedziach znajduje się użyteczny opis tych strategii.

Jak czytać funkcje wywołania zwrotnego związanego z dymem w jquery

Mnebuerquo
źródło
32

może metoda unbind zadziała dla ciebie

$("#myimage").unbind("click");
John Boker
źródło
30

Musiałem ustawić to zdarzenie na zero, używając rekwizytów i attr. Nie mogłem tego zrobić z jednym lub drugim. Nie mogłem też zmusić .unbind do pracy. Pracuję nad elementem TD.

.prop("onclick", null).attr("onclick", null)
dwhittenburg
źródło
1
Głosowałem za tym, ponieważ starałem się rozwiązać unblur przez około 30 minut. „.unbind” nie działało, „.prop” nie działało, „.attr” nie działało, ale ta sztuczka z .prop i .attr razem działała. dziwny. Używam Chrome z jquery 1.7.2
Jeremy
To samo tutaj! próbowałem usunąć zdarzenie kliknięcia z prostego tagu <a>! Dzięki za to. W moim przypadku wystarczy .prop („onclick”, null).
Jan Lobau
to samo tutaj. unbind i off nie działały dla mnie na FF z jq 1.7.2 i .prop („onclick”, null) również było wystarczające w moim przypadku
bryanallott
4
Myślę, że powodem, dla którego powyższe metody nie działały dla was, jest sposób ich skonfigurowania. Jeśli napisałeś moduł obsługi zdarzeń w DOM, to tak, wyczyszczenie tego atrybutu jest konieczne, aby wyczyścić moduł obsługi zdarzeń, jednak myślę, że większość osób (w tym ja) chce trzymać takie rzeczy (javascrip, procedury obsługi zdarzeń itp.) Poza DOM, więc gdy chcemy skonfigurować moduł obsługi zdarzeń, używamy czegoś takiego $("#elementId").click(function(){//Event execution code goes here});, aby w ogóle nie było go na stronie HTML. Aby wyjaśnić, że faktycznie musimy użyć .unbind()lub preferowanego.off()
VoidKing
Oto jak ktoś, kto właśnie spędził godzinę, aby odkryć, że właściwości dodane za pomocą jQuery nie wyświetlają się w panelu elementów Chrome. Próbowałem unbindi offnie rozwiązało problemu. Dziękuję Ci bardzo!
Renan
13

Jeśli zdarzenie jest dołączone w ten sposób , a cel ma zostać odłączony:

$('#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.

});​

źródło
11

Być może dodajesz onclickmoduł obsługi jako znacznik wbudowany:

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

Jeśli tak, jquery .off()lub .unbind()nie będzie działać. Musisz również dodać oryginalny moduł obsługi zdarzeń w jquery:

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

Następnie jquery ma odwołanie do procedury obsługi zdarzeń i może ją usunąć:

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

VoidKing wspomina o tym nieco bardziej skośnie w komentarzu powyżej.

davaus
źródło
9

Zaktualizowano w 2014 r

Korzystając z najnowszej wersji jQuery, możesz teraz odłączyć wszystkie zdarzenia w przestrzeni nazw, po prostu wykonując te czynności $( "#foo" ).off( ".myNamespace" );

alexpls
źródło
8

Najlepszym sposobem na usunięcie wbudowanego zdarzenia onclick jest $(element).prop('onclick', null);

Shahrukh Azeem
źródło
8

Dla remove WSZYSTKICH event-handlers to właśnie działało dla mnie:

Usunięcie wszystkich programów obsługi zdarzeń oznacza posiadanie zwykłego interfejsu HTML structurebez wszystkich event handlersdołączonych do niego elementi jego child nodes. Aby to zrobić, jQuery's clone()pomógł.

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);

Dzięki temu będziemy mieć clonemiejsce na „ originalbez” event-handlers.

Powodzenia...

Akash
źródło
7

Dzięki za informację. bardzo pomocne Użyłem go do blokowania interakcji strony w trybie edycji przez innego użytkownika. Użyłem go w połączeniu z ajaxComplete. Niekoniecznie to samo zachowanie, ale nieco podobne.

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

function executePageLock(){
    //do something
}
użytkownik_jquery
źródło
5

W przypadku, gdy .on()wcześniej użyto metody z określonym selektorem, jak w poniższym przykładzie:

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

Zarówno unbind()i .off()metody nie zadziała.

Jednakże .undelegate () Sposób może być wykorzystywany, aby całkowicie usunąć z obsługi zdarzenia dla wszystkich elementów, które pasują do wybranego przełącznika:

$("body").undelegate(".dynamicTarget", "click")
Ilia Rostowcew
źródło
1
Przewinąłem całą stronę, szukając tego rozwiązania, działało jak urok.
Abhishek Pandey,
4

Jeśli używasz, $(document).on()aby dodać detektor do dynamicznie tworzonego elementu, być może będziesz musiał użyć następujących elementów, aby go usunąć:

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

// remove the listener
$(document).off("click", ".element");
ow3n
źródło
2

jeśli ustawisz onclickvia html, musiszremoveAttr ($(this).removeAttr('onclick'))

jeśli ustawisz to za pomocą jquery (jak po pierwszym kliknięciu w moich przykładach powyżej), musisz to zrobić unbind($(this).unbind('click'))

Ishan Liyanage
źródło
2

Wiem, że to się spóźnia, ale dlaczego nie użyć zwykłego JS do usunięcia zdarzenia?

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

lub, jeśli używasz nazwanej funkcji jako procedury obsługi zdarzeń:

function eh(event){...}
var myElement = document.getElementById("your_ID");
myElement.addEventListener("click",eh); // add event handler
myElement.removeEventListener("click",eh); //remove it
Silviu Preda
źródło
Dobra sugestia, wolę używać natywnego języka JavaScript, jeśli jest dostępny
Michiel,
1

Wszystkie opisane podejścia nie działały dla mnie, ponieważ dodawałem zdarzenie click on()do do dokumentu, w którym element został utworzony w czasie wykonywania:

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


Moje obejście:

Ponieważ nie mogłem odłączyć klasy „.button”, właśnie przypisałem inną klasę do przycisku, który miał te same style CSS. W ten sposób moduł obsługi zdarzeń na żywo / zdarzenia zignorował wreszcie kliknięcie:

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

Mam nadzieję, że to pomaga.

Kai Noack
źródło
1

Mam nadzieję, że mój poniższy kod wyjaśnia wszystko. 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
źródło
1
dlaczego })(jQuery);przenosicie się do IIFE, skoro jest już dostępny na całym świecie?
Bryan P.
2
Dobre pytanie Bryan. Ta metoda została wprowadzona do mojego genu z powodu praktyki. - Może istnieć możliwość, że wtyczka nie będąca jquery będzie mieć zmienną $, dlatego nie mogę bezpośrednio użyć $. - Częste użycie słowa „jQuery” w pliku skryptu js może zwiększyć rozmiar bajtu pliku, gdzie jQuery jest łańcuchem 6-bajtowym. Dlatego wolę używać „$” lub dowolnej zmiennej jednobajtowej.
mysticmo
0

Po prostu usuń to z przycisku:

$('.classname').click(function(){
$( ".classname" ).remove();
});
Mitra
źródło