Estou vinculando um evento de clique com um botão:
$('#myButton').bind('click', onButtonClicked);
Em um cenário, isso está sendo chamado várias vezes; portanto, quando faço um trigger
, vejo várias chamadas ajax que desejo impedir.
Como faço bind
apenas se não estiver vinculado antes.
Respostas:
Atualização 24 de agosto '12 : No jQuery 1.8, não é mais possível acessar os eventos do elemento usando
.data('events')
. (Veja este bug para obter detalhes.) É possível acessar os mesmos dados comjQuery._data(elem, 'events')
uma estrutura de dados interna, que não é documentada e, portanto, não tem 100% de garantia de permanecer estável. No entanto, isso não deve ser um problema, e a linha relevante do código do plug-in acima pode ser alterada para o seguinte:Os eventos do jQuery são armazenados em um objeto de dados chamado
events
, para que você possa pesquisar:Seria melhor, é claro, se você pudesse estruturar seu aplicativo para que esse código seja chamado apenas uma vez.
Isso pode ser encapsulado em um plugin:
Você pode ligar para:
fonte
<a>
? Porque quando eu tento, diz sobrejQuery._data()
o seguinte erroTypeError: a is undefined
var data = jQuery._data(this[0], 'events')[type];
em uma tentativa de captura e retornar falso na captura. Se nenhum evento estiver vinculado a esse [0], uma chamada para [type] causará alguma variação de "Não é possível obter propriedade 'clique' 'de referência indefinida ou nula" e, obviamente, isso também informa o que você precisa saber.for (var i = 0; i < data.length; i++) { if (data[i].handler.toString() === fn.toString()) { return true; } }
Mais uma maneira - marque esses botões com uma classe e filtro CSS:
Nas versões recentes do jQuery, substitua
bind
poron
:fonte
Se você estiver usando o jQuery 1.7+:
Você pode ligar
off
anteson
:Se não:
Você pode simplesmente desatar o primeiro evento:
fonte
.unbind('click', onButtonClicked)
. Veja o manual$(sel).unbind("click.myNamespace");
$('#myButton').unbind('click', onButtonClicked).bind('click', onButtonClicked);
A melhor maneira que vejo é usar live () ou delegate () para capturar o evento em um pai e não em cada elemento filho.
Se o botão estiver dentro de um elemento #parent, você poderá substituir:
$('#myButton').bind('click', onButtonClicked);
de
$('#parent').delegate('#myButton', 'click', onButtonClicked);
mesmo que #myButton ainda não exista quando esse código for executado.
fonte
Eu escrevi um plugin muito pequeno chamado "once" que faz isso. Execute dentro e fora do elemento.
E simplesmente:
fonte
off
remove todos os manipuladores para o tipo especificado? Ou seja, se houvesse um manipulador de cliques separado e não relacionado, mas no mesmo item, esse também não seria removido?Por que não usar isso
unbind()
antesbind()
fonte
$('#myButton').off().on('click', onButtonClicked);
também funciona para mim.Aqui está a minha versão:
Uso:
fonte
Baseado na resposta @ konrad-garus, mas usando
data
, já que acredito queclass
deve ser usado principalmente para estilizar.fonte
Para evitar verificar / ligar / desligar, você pode mudar sua abordagem! Por que você não usa Jquery .on ()?
Como o Jquery 1.7, .live (), .delegate () está obsoleto, agora você pode usar .on () para
Isso significa que você pode anexar um evento a um elemento pai que ainda existe e anexar elementos filhos, estejam eles presentes ou não!
Quando você usa .on () assim:
Você pega o evento, clique no pai e ele procura o filho '#myButton', se existir ...
Portanto, quando você remove ou adiciona um elemento filho, não precisa se preocupar em adicionar ou remover a ligação de evento.
fonte
.off
, acredito que removeria manipuladores não relacionados no processo.Experimentar:
fonte
fonte
Em junho de 2019, atualizei a função (e ela está funcionando para o que eu preciso)
fonte
JQuery tem solução :
equivalente:
fonte