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

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

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.


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.


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



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)

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.

});​

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.


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


8

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


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


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
}

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

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


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


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

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.


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>


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();
});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.