2012-04-02 14 views
18

Si asigno dos veces un controlador al evento OnClick de un elemento, el controlador se ejecutará dos veces. Pero quiero cambiar esto, incluso si lo asigno dos veces, el controlador solo se ejecutará una vez.Agregue un controlador OnClick con jQuery solo una vez, incluso si se vuelve a llamar

ejemplo sin sentido para demostrar tema:

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

Así que he añadido el manejador de dos veces. Ahora cuando hago clic en un elemento con esa clase, obtengo dos cuadros de alerta.

La pregunta es, ¿cómo la restrinjo para que solo obtenga un cuadro de alerta?

+1

¿Por qué necesitaría agregar el evento dos veces? – root

+1

Hay una función ejecutada en esta página cada vez que hay una devolución de datos, para agregar el controlador a los elementos creados dinámicamente. Sin embargo, cualquier elemento que existiera anteriormente tiene el controlador dos veces ... – msigman

+2

Creo que debes replantear tu enfoque para evitar el enlace dos veces, pero si estás en una crisis, supongo que podrías usar '$ ('. Button') .off ('click'). on ('click', function() {...}); 'como aquí: http://jsfiddle.net/SsRxv/ – hyperslug

Respuesta

24

Si .one() es en realidad lo que está buscando (quitando el controlador de eventos después de que se haya activado una vez) entonces creo que es la respuesta correcta. De lo contrario, puede desvincular el evento antes de vincularlo:

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

Debería funcionar.

Editar: dado que esta respuesta sigue recibiendo votos, agregaré otra (mejor en la mayoría de los casos) solución que funcionará al menos en el caso del OP. Cuando se trata de contenido agregado dinámicamente, simplemente use jQuery's on() en un elemento padre en lugar de aplicar el controlador de eventos directamente en el elemento.

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

4

Use uno. http://api.jquery.com/one/

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

Tenga en cuenta que esto hará que' alert() ' mostrar solo por un clic e ignorar los clics posteriores. El problema del OP es que 'alerta()' se muestra más de una vez por clic. – leepowers

+0

powerbuoy tiene la respuesta entonces. –

-1

creo que no hay ningún punto de añadir la función dos veces. Sin embargo, si tiene que hacerlo, puede agregar return false a una de las funciones.

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

Para que los eventos activa sólo una vez, se unen sólo una vez. Al agregar dinámicamente elementos, enlazar el controlador de eventos al elemento padre usando on():

ver este 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> 

Nota cómo los controladores de eventos se registran con on() sólo una vez. El código que agrega dinámicamente elementos no registra los controladores de eventos.

5

un pequeño truco que puede ayudar:

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

    alert('here'); 

).addClass("clickadded"); 
0

Aquí es un método que estoy usando, similar al método de Miquel en algunos aspectos.

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

utilizar de esta manera,

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

vez también es compatible con un parámetro de lo que puede tener diferentes tipos

1

También puede remover cualquier evento existente haga clic en la función con la función de apagado (' clic "):

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

lo resuelto por una bandera, sé que no es el mejor con sólo una idea

if (!alreadyBound) { 
    $('.button').bind('click', submitEvtHandler); 
    alreadyBound = true; 
} 
Cuestiones relacionadas