Eu estou tentando entender essa diferença particular entre os diretos e delegados manipuladores de eventos usando o jQuery .no () método . Especificamente, a última frase deste parágrafo:
Quando a
selector
é fornecido, o manipulador de eventos é chamado de delegado . O manipulador não é chamado quando o evento ocorre diretamente no elemento vinculado, mas apenas para descendentes (elementos internos) que correspondem ao seletor. jQuery borbulha o evento do destino do evento até o elemento em que o manipulador está anexado (ou seja, do elemento mais interno ao mais externo) e executa o manipulador para quaisquer elementos ao longo desse caminho que correspondam ao seletor.
O que significa "executa o manipulador para quaisquer elementos"? Eu fiz uma página de teste para experimentar o conceito. Mas as duas construções a seguir levam ao mesmo comportamento:
$("div#target span.green").on("click", function() {
alert($(this).attr("class") + " is clicked");
});
ou,
$("div#target").on("click", "span.green", function() {
alert($(this).attr("class") + " is clicked");
});
Talvez alguém possa se referir a um exemplo diferente para esclarecer esse ponto? Obrigado.
Respostas:
Caso 1 (direto):
== Ei! Quero que todo span.green dentro do div # target seja ouvido: quando você clica em, faça X.
Caso 2 (delegado):
== Ei, div # target! Quando qualquer um dos elementos filhos "span.green" for clicado, faça X com eles.
Em outras palavras...
No caso 1, cada uma dessas extensões recebeu instruções individualmente. Se novos spans forem criados, eles não terão ouvido as instruções e não responderão aos cliques. Cada período é diretamente responsável por seus próprios eventos.
No caso 2, apenas o contêiner recebeu a instrução; é responsável por perceber cliques em nome de seus elementos filhos. O trabalho de captura de eventos foi delegado . Isso também significa que a instrução será executada para elementos filho criados no futuro.
fonte
on()
permitem dois argumentos quando isso seria o mesmo que usarclick()
?e.target
será o destino inicial do evento click (pode ser um nó filho sespan.green
tiver filhos). De dentro do manipulador, você deve usar athis
referência. Veja este violino .A primeira maneira,
$("div#target span.green").on()
vincula um manipulador de cliques diretamente aos espaços que correspondem ao seletor no momento em que o código é executado. Isso significa que se outras extensões forem adicionadas mais tarde (ou tiverem sua classe alterada para corresponder), elas perderão e não terão um manipulador de cliques. Isso também significa que, se você remover posteriormente a classe "verde" de um dos períodos em que o manipulador de cliques continuará sendo executado - o jQuery não acompanhará como o manipulador foi atribuído e verificará se o seletor ainda corresponde.A segunda maneira,
$("div#target").on()
vincula um manipulador de cliques às divs que correspondem (novamente, isso é contra as que correspondem naquele momento), mas quando um clique ocorre em algum lugar na div, a função manipuladora será executada apenas se o clique ocorreu não apenas na div, mas em um elemento filho que corresponde ao seletor no segundo parâmetro para.on()
"span.green". Feito dessa maneira, não importa quando essas extensões filho foram criadas, clicar nelas ainda executará o manipulador.Portanto, para uma página que não está adicionando ou alterando dinamicamente seu conteúdo, você não notará diferença entre os dois métodos. Se você estiver adicionando elementos filho adicionais dinamicamente, a segunda sintaxe significa que você não precisa se preocupar em atribuir manipuladores de cliques a eles, porque você já fez isso uma vez no pai.
fonte
A explicação do N3dst4 é perfeita. Com base nisso, podemos assumir que todos os elementos filhos estão dentro do corpo; portanto, precisamos usar apenas isso:
Funciona com evento direto ou delegado.
fonte
$('body').on()
delegação de.element
deve se comportar exatamente da mesma forma que a nativadocument.body.addEventHandler()
com umif (Event.target.className.matches(/\belement\b/))
retorno de chamada. Pode ser um pouco mais lento no jquery devido à$.proxy
sobrecarga, mas não me cite nisso.Tangencial para o OP, mas o conceito que me ajudou a desvendar a confusão com esse recurso é que os elementos vinculados devem ser os pais dos elementos selecionados .
.on
..on()
.A delegação não funciona como .find (), selecionando um subconjunto dos elementos ligados. O seletor se aplica apenas a elementos filho estritos.
é muito diferente de
Em particular, para obter as vantagens, o @ N3dst4 sugere com "elementos criados no futuro" que o elemento ligado deve ser um pai permanente . Então as crianças selecionadas podem ir e vir.
EDITAR
Lista de verificação de por que o delegado
.on
não funcionaMotivos complicados pelos quais
$('.bound').on('event', '.selected', some_function)
pode não funcionar:.on()
.stopPropagation()
.(Omitindo razões menos complicadas, como um seletor com erros ortográficos.)
fonte
Escrevi um post com uma comparação de eventos diretos e delegados. Eu comparo js puros, mas tem o mesmo significado para jquery, que apenas o encapsula.
A conclusão é que a manipulação de eventos delegados é para a estrutura dinâmica do DOM, onde os elementos vinculados podem ser criados enquanto o usuário interage com a página (não é necessário vincular novamente), e a manipulação direta de eventos é para os elementos estáticos do DOM, quando sabemos que a estrutura não será alterada.
Para mais informações e comparação completa - http://maciejsikora.com/standard-events-vs-event-delegation/
Usar manipuladores sempre delegados, que eu vejo atualmente muito na moda, não é o caminho certo, muitos programadores o usam porque "deve ser usado", mas a verdade é que os manipuladores diretos de eventos são melhores para alguma situação e a escolha de qual método deve ser suportado pelo conhecimento das diferenças.
fonte