2012-04-02 10 views
18

Jeśli przypiszesz moduł obsługi do zdarzenia OnClick elementu dwukrotnie, program obsługi zostanie wykonany dwukrotnie. Ale chcę to zmienić, więc nawet jeśli przydzielę to dwukrotnie, handler wykona tylko jeden raz.Dodaj handler'a OnClick z jQuery tylko raz - nawet jeśli zostanie ponownie wywołany

bezsensowny przykład wykazać problem:

$('.button').click(
    function(){ 
     alert('here'); 
}); 
$('.button').click(
    function(){ 
     alert('here'); 
}); 

Więc Dodałem obsługi dwukrotnie. Teraz, gdy kliknę element z tą klasą, otrzymam dwa pola ostrzeżeń.

Pytanie brzmi, w jaki sposób mogę go ograniczyć, aby otrzymać tylko jedno pole ostrzeżenia?

+1

Dlaczego trzeba dodać wydarzenie dwa razy? – root

+1

Istnieje funkcja wykonywana na tej stronie za każdym razem, gdy występuje odświeżenie, w celu dodania modułu obsługi do dynamicznie tworzonych elementów. Jednak każdy element, który wcześniej istniał, ma teraz dwukrotnie obsługę ... – msigman

+2

Myślę, że musisz ponownie przemyśleć swoje podejście, aby uniknąć podwójnego wiązania, ale jeśli jesteś w kryzysie, przypuszczam, że możesz użyć '$ (". Button ") .off ("kliknij"). on ("kliknij", funkcja() {...}); "jak tutaj: http://jsfiddle.net/SsRxv/ – hyperslug

Odpowiedz

24

Jeśli .one() jest w rzeczywistości, co jesteś po (usuwanie obsługi zdarzeń po to został wywołany raz) to uważam, że to jest poprawna odpowiedź. Jeśli nie, możesz odwiązać zdarzenie przed powiązaniem:

var myEventHandler = function() {alert('hello')}; 
$('a').unbind('click', myEventHandler); 
$('a').bind('click', myEventHandler); 

Powinien działać.

Edycja: ponieważ ta odpowiedź wciąż podnosi liczbę głosów, dodam inne (w większości przypadków lepsze) rozwiązanie, które będzie działać przynajmniej w przypadku PO. W przypadku dynamicznie dodawanych treści wystarczy użyć elementu jQuery o numerze on() w elemencie nadrzędnym zamiast stosowania procedury obsługi zdarzenia bezpośrednio w elemencie.

http://api.jquery.com/on/

4

Użyj jednego. http://api.jquery.com/one/

$(".button").one('click', function(){ 
    alert('....') 
}); 
+8

Uwaga, spowoduje to, że' alert() ' pokaż tylko jedno kliknięcie i ignoruj ​​kolejne kliknięcia. Problem PO polega na tym, że 'alert()' pokazuje się więcej niż raz na kliknięcie. – leepowers

+0

powerbuoy ma odpowiedź wtedy. –

-1

myślę, że nie ma sensu, aby dodać funkcję dwukrotnie. Jednak, jeśli musisz, możesz dodać jedną z funkcji return false.

$('.button').click(
    function(){ 
     return false; 
     alert('here'); 
}); 
$('.button').click(
    function(){ 
     alert('here'); 
});​ 
5

Aby mieć zdarzenia wyzwalany tylko raz, wiązać je tylko raz. Kiedy dynamicznie dodawanie elementów, wiążą obsługi zdarzeń do elementu nadrzędnego przy użyciu on():

Zobacz ten jsfiddle:

<div id="container"> 
<p>Paragraph #1</p> 
</div> 

<div> 
<button id="add">Add Elements</button> 
</div> 

<script type="text/javascript"> 
var n = 1; 
$('#add').click(function() { 
    $('#container').append('<p>Paragraph #' + ++n + '</p>'); 
}); 
$('#container').on('click', 'P', function() { 
    alert($(this).text()); 
}); 
</script> 

zauważyć jak obsługi zdarzeń są zarejestrowane on() tylko raz. Kod, który dynamicznie dodaje elementy, nie rejestruje procedur obsługi zdarzeń.

5

mały trick, które mogą pomóc:

jQuery(".button:not(.clickadded)").click(function(){ 

    alert('here'); 

).addClass("clickadded"); 
0

Oto metoda używam, podobna do metody Miquel w pewnym sensie.

$.prototype.once = function() { 
    var ret = this.not(function() { 
     return this.once; 
    }); 
    this.each(function(id, el) { 
     el.once = true; 
    }); 
    return ret; 
}; 

Używaj go tak,

$('#footer') 
    .once() 
    .click(function(){ 
     console.log('click the footer'); 
    }); 

obsługuje Raz również parametr, dzięki czemu można mieć różne typy

1

Można również usunąć wszelkie istniejące wydarzenia kliknij funkcji z funkcją wyłączenia (” kliknij "):

$('.button').off('click').click(function() { 
    ... 
}); 
1

Rozwiązałem go flagą, wiem, że nie jest najlepszy według pomysłu

if (!alreadyBound) { 
    $('.button').bind('click', submitEvtHandler); 
    alreadyBound = true; 
} 
Powiązane problemy