Eu tenho o seguinte código:
function someMethod()
{
$(obj).click(function {});
}
someMethod é chamado duas vezes e, portanto, o evento de clique é vinculado duas vezes. Como posso vinculá-lo apenas uma vez?
Eu tenho o seguinte código:
function someMethod()
{
$(obj).click(function {});
}
someMethod é chamado duas vezes e, portanto, o evento de clique é vinculado duas vezes. Como posso vinculá-lo apenas uma vez?
Respostas:
Se você puder aplicá-lo, provavelmente queira dar uma olhada em event.preventDefault e event.stopPropagation OU desvincular e vincular a cada vez, dentro de seu 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 {}); }
Além da resposta de pna, você pode querer pensar sobre o namespace de seu evento para não desvincular todos os eventos de clique acidentalmente.
function someMethod () { $ (obj) .unbind ('click.namespace'). bind ('click.namespace', function () {}); }
$(obj).off()
e $(obj).on()
respectivamente. Caso contrário, o namespacing ajudou e funcionou. Obrigado!
Não existe um método integrado para determinar se você já vinculou esta função específica. Você pode vincular várias funções de clique a um objeto. Por exemplo:
$('#id').bind('click', function(){
alert('hello');
});
$('#id').bind('click', function(){
alert('goodbuy');
});
se você fizer o acima quando o objeto for clicado, ele irá alertá-lo. Para garantir que apenas uma função esteja associada ao evento click, desassocie o manipulador de eventos click e vincule a função desejada desta forma:
$(obj).unbind('click').bind('click', function(){... });
A solução óbvia é não ligar someMethod()
duas vezes. Se você não pode consertar isso, você pode manter uma variável de estado para que ela só se vincule uma vez, assim:
function someMethod()
{
if (!someMethod.bound) {
$(obj).click(function() {});
someMethod.bound = true;
}
}
Observação: isso usa uma propriedade da própria função em vez de introduzir uma variável global para controlar se ela foi associada. Você também pode usar uma propriedade no próprio objeto.
Você pode ver como funciona aqui: http://jsfiddle.net/jfriend00/VHkxu/ .
Ou use a função one () do jQuery, que é semelhante a on (), mas só dispara o evento uma vez, mesmo se você ligá-lo várias vezes.
O jQuery torna a chamada de alguma função possível apenas uma vez muito fácil:
function someMethod()
{
$(obj).click(function() {});
this.someMethod = $.noop;
}
jQuery.noop
tem apenas um caractere menor que function(){}
, então é meio bobo dizer que está "ajudando" aqui, apenas fornecendo uma função vazia. Aqui está um exemplo não-jQuery e não-método desta solução geral:var fn = function(){ fn = function(){}; do stuff; };
$
lugar
Esta é uma sugestão, já que não conheço sua lógica. Pode ou não funcionar para você.
Tente combinar as funções jquery live () e one () para obter um resultado melhor do que as religações de eventos.
Os casos especiais funcionam quando você tem 2 elementos DOM (pai e filho). Live () no nó pai certifica-se de que o evento será invocado e, em seguida, chama one () para registrar dinamicamente o evento que seria executado apenas uma vez. (isso fornece funcionalidade semelhante, como religações).
One()
função funcionou em, chrome
mas não funcionou safari
em Mac
.
Você pode adicionar classe css aos elementos vinculados e, em seguida, filtrá-los:
function someMethod()
{
$(obj).not('.click-binded')
.click(function {})
.addClass('click-binded');
}
Este método também pode ser usado para plug-ins:
$(obj).not('.datetimepicker-applied')
.datetimepicker()
.addClass('datetimepicker-applied');
var bound = false;
function someMethod()
{
if(!bound)
{
$(obj).click(function {});
bound = true;
}
}
mas eu provavelmente investigaria por que ele está sendo chamado duas vezes antes de fazer algum tipo de solução alternativa.
bound
is attach to ao someMethod()
invés de poluir o namespace global.
Você pode usar esta função de extensão 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);
}
};
Em vez de fazer isso
$("button").on("click", function(){
alert("You Clicked On A Button");
});
Você faz isso
$("button").once("click", function(){
alert("You Clicked On A Button");
}, "btnHandler");
Agora, quando tenho uma função em torno disso
function addBtnHandler() {
$("button").once("click", function() {
alert("You Clicked On A Button");
}, "btnHandler");
}
E eu chamo isso várias vezes
addBtnHandler();
addBtnHandler();
addBtnHandler();
Só faz isso uma vez.
Observe que a extensão funciona verificando uid e type. Isso significa que você pode ligar diferentes tipos de manipuladores com o mesmo uid, você pode ou não querer isso. Para alterá-lo, edite.
var dataStr = type+"-handler-"+uid;
Com algo como
var dataStr = "handler-"+uid;
Eu também estava tentando usar o método off e on de jquery para vincular evento apenas uma vez com o elemento dom que ainda não existe ou o elemento dom ainda não foi criado.
$('.select').off('event').on('event', 'selector', function(e){ // });
Este código não estava funcionando corretamente
Eu descobri um método muito lucrativo que é 'um' método. É muito útil quando você deseja vincular um evento apenas uma vez.
Você pode encontrar o documento aqui http://api.jquery.com/one/
É o mesmo que o método 'ligado', mas é diferente com seu comportamento de não se manter no evento para seletores múltiplos.
$('body').one('click', 'selector', function(){ // do your stuff here });
Você pode conseguir isso com JS puro, usando o método addEventListener e sua opção uma vez
target.addEventListener('click', handler, {once: true});