Estoy vinculando un evento de clic con un botón:
$('#myButton').bind('click', onButtonClicked);
En un escenario, esto se llama varias veces, por lo que cuando hago una trigger
, veo varias llamadas ajax que quiero evitar.
¿Cómo lo hago bind
solo si no está vinculado antes?
Respuestas:
Actualización 24 de agosto '12 : en jQuery 1.8, ya no es posible acceder a los eventos del elemento utilizando
.data('events')
. (Consulte este error para obtener más detalles). Es posible acceder a los mismos datos conjQuery._data(elem, 'events')
una estructura de datos interna, que no está documentada y, por lo tanto, no se garantiza que permanezca estable al 100%. Sin embargo, esto no debería ser un problema, y la línea relevante del código del complemento anterior se puede cambiar a lo siguiente:Los eventos jQuery se almacenan en un objeto de datos llamado
events
, por lo que puede buscar en esto:Sería mejor, por supuesto, si pudiera estructurar su aplicación para que este código solo se llame una vez.
Esto podría encapsularse en un complemento:
Entonces puedes llamar a:
fuente
<a>
? Porque cuando lo intento dice enjQuery._data()
el siguiente errorTypeError: a is undefined
var data = jQuery._data(this[0], 'events')[type];
en un intento de captura y devolvería falso en la captura. Si no hay eventos vinculados a esto [0], una llamada a [type] causará alguna variación de "No se puede obtener la propiedad 'clic' de referencia indefinida o nula" y obviamente eso también le dice lo que necesita saber.for (var i = 0; i < data.length; i++) { if (data[i].handler.toString() === fn.toString()) { return true; } }
Una forma más: marque dichos botones con una clase CSS y filtro:
En versiones recientes de jQuery, reemplace
bind
conon
:fuente
Si usa jQuery 1.7+:
Puedes llamar
off
anteson
:Si no:
Simplemente puede desvincularlo primer evento:
fuente
.unbind('click', onButtonClicked)
. Vea el manual$(sel).unbind("click.myNamespace");
$('#myButton').unbind('click', onButtonClicked).bind('click', onButtonClicked);
La mejor manera que veo es usar live () o delegate () para capturar el evento en un elemento primario y no en cada elemento secundario.
Si su botón está dentro de un elemento #parent, puede reemplazar:
$('#myButton').bind('click', onButtonClicked);
por
$('#parent').delegate('#myButton', 'click', onButtonClicked);
incluso si #myButton aún no existe cuando se ejecuta este código.
fuente
Escribí un plugin muy pequeño llamado "una vez" que hace eso. Ejecutar de vez en cuando en el elemento.
Y simplemente:
fuente
off
elimina todos los controladores para el tipo dado? Es decir, si hubiera un controlador de clics separado sin relación pero en el mismo elemento, ¿no se eliminaría también?¿Por qué no usar esto?
unbind()
antes debind()
fuente
$('#myButton').off().on('click', onButtonClicked);
También funciona para mí.Aquí está mi versión:
Uso:
fuente
Basado en la respuesta @ konrad-garus, pero usando
data
, ya que creo queclass
debería usarse principalmente para el estilo.fuente
Para evitar marcar / vincular / desvincular, ¡puede cambiar su enfoque! ¿Por qué no usas Jquery .on ()?
Como Jquery 1.7, .live (), .delegate () está en desuso, ahora puede usar .on () para
¡Significa que puede adjuntar un evento a un elemento primario que aún existe y adjuntar elementos secundarios si están presentes o no!
Cuando usas .on () así:
Captura el evento, haz clic en padre y busca hijo '#myButton' si existe ...
Por lo tanto, cuando elimine o agregue un elemento secundario, no tendrá que preocuparse de si desea agregar o eliminar el enlace del evento.
fuente
.off
, creo que eliminaría los controladores no relacionados en el proceso.Tratar:
fuente
fuente
A partir de junio de 2019, he actualizado la función (y está funcionando para lo que necesito)
fuente
JQuery tiene solución :
equivalente:
fuente