Tengo el siguiente código:
function someMethod()
{
$(obj).click(function {});
}
someMethod se llama dos veces y, por lo tanto, el evento de clic se enlaza dos veces. ¿Cómo puedo hacer que se una solo una vez?
Si puede aplicarlo, probablemente quiera echar un vistazo a event.preventDefault y event.stopPropagation O desvincular y vincular cada vez, dentro de su método como
function someMethod()
{
$(obj).off('click').on('click', function(e) {
// put your logic in here
});
}
function someMethod() { $(obj).off('click.namespace').on('click.namespace', function {}); }
Además de la respuesta de pna, es posible que desee pensar en el espacio de nombres de su evento para no anular la vinculación accidental de todos los eventos de clic.
function someMethod () { $ (obj) .unbind ('click.namespace'). bind ('click.namespace', function () {}); }
$(obj).off()
y $(obj).on()
respectivamente. De lo contrario, el espacio de nombres ayudó y funcionó. ¡Gracias!
No hay un método integrado para determinar si ya ha vinculado esta función en particular. Puede vincular varias funciones de clic a un objeto. Por ejemplo:
$('#id').bind('click', function(){
alert('hello');
});
$('#id').bind('click', function(){
alert('goodbuy');
});
Si hace lo anterior cuando se hace clic en el objeto, le avisará hola y luego adiós. Para asegurarse de que solo una función esté vinculada al evento de clic, desvincule el controlador de eventos de clic y luego vincule la función deseada de esta manera:
$(obj).unbind('click').bind('click', function(){... });
La solución obvia es no llamar someMethod()
dos veces. Si no puede solucionarlo, puede mantener una variable de estado para que solo se una una vez de esta manera:
function someMethod()
{
if (!someMethod.bound) {
$(obj).click(function() {});
someMethod.bound = true;
}
}
Nota: esto usa una propiedad de la función en sí en lugar de introducir una variable global para realizar un seguimiento de si se ha vinculado. También puede utilizar una propiedad en el propio objeto.
Puedes verlo funcionar aquí: http://jsfiddle.net/jfriend00/VHkxu/ .
O use la función one () de jQuery que es similar a on () pero solo activa el evento una vez, incluso si lo vincula varias veces.
jQuery hace que llamar a alguna función sea posible solo una vez bastante fácil:
function someMethod()
{
$(obj).click(function() {});
this.someMethod = $.noop;
}
jQuery.noop
es solo un carácter más corto que function(){}
, por lo que es un poco tonto decir que "ayuda" aquí, solo que proporciona una función vacía. Aquí hay un ejemplo sin método de jQuery de esta solución general:var fn = function(){ fn = function(){}; do stuff; };
$
en su lugar
Esta es una sugerencia ya que no conozco su lógica. Puede o no funcionar para usted.
Intente combinar las funciones jquery live () y one () le dará un mejor resultado que las revinculaciones de eventos.
Los casos especiales funcionan cuando tienes 2 elementos DOM (padre e hijo). Live () en el nodo principal se asegura de que se invoque el evento y luego llama a one () para registrar dinámicamente el evento que se ejecutará solo una vez. (esto proporciona una funcionalidad similar a la de volver a enlazar).
One()
la función funcionó chrome
pero no funcionó safari
en Mac
.
Puede agregar la clase css a los elementos enlazados y luego filtrarlos:
function someMethod()
{
$(obj).not('.click-binded')
.click(function {})
.addClass('click-binded');
}
Este método también se puede utilizar para complementos:
$(obj).not('.datetimepicker-applied')
.datetimepicker()
.addClass('datetimepicker-applied');
var bound = false;
function someMethod()
{
if(!bound)
{
$(obj).click(function {});
bound = true;
}
}
pero probablemente investigaría por qué se llama dos veces antes de hacer algún tipo de solución.
bound
se adjunta en someMethod()
lugar de contaminar el espacio de nombres global.
Si desea vincularse al objeto solo una vez, debe implementar una bandera y ceñirse a ese objeto.
Por ejemplo:
if($('#id') && $('#id').data('done') == null)) {
$('#id').bind('click', function() {
alert('hello');
});
$('#id').data('done', true);
}
Puede utilizar esta función de extensión jQuery.
$.fn.once = function (type, fn, uid) {
if(uid == undefined) {
console.error("Called $.once without uid\n", this, "\n", fn);
}
var dataStr = type+"-handler-"+uid;
if(!this.data(dataStr)) {
this.data(dataStr, true);
this.on(type, fn);
}
};
En lugar de hacer esto
$("button").on("click", function(){
alert("You Clicked On A Button");
});
Ya haces esto
$("button").once("click", function(){
alert("You Clicked On A Button");
}, "btnHandler");
Ahora, cuando tengo una función a su alrededor
function addBtnHandler() {
$("button").once("click", function() {
alert("You Clicked On A Button");
}, "btnHandler");
}
Y lo llamo varias veces
addBtnHandler();
addBtnHandler();
addBtnHandler();
Solo lo hace una vez.
Observe que la extensión funciona verificando tanto uid como type. Esto significa que puede vincular diferentes tipos de controladores con el mismo uid, puede que desee o no. Para cambiarlo editar.
var dataStr = type+"-handler-"+uid;
Con algo como
var dataStr = "handler-"+uid;
También estaba tratando de usar el método de activación y desactivación de jquery para vincular el evento solo una vez con el elemento dom que aún no existe o el elemento dom aún no se ha creado.
$('.select').off('event').on('event', 'selector', function(e){ // });
Este código no funcionaba correctamente
Me encontré con un método muy lucrativo que es 'un' método. Es muy útil cuando desea vincular un evento solo una vez.
Puedes encontrar el documento aquí http://api.jquery.com/one/
Esto es lo mismo que el método 'on' pero diferente en su comportamiento con no quedarse con el evento para múltiples selectores.
$('body').one('click', 'selector', function(){ // do your stuff here });
Puede lograr esto con JS puro, usando el método addEventListener y su opción once
target.addEventListener('click', handler, {once: true});