Gostaria de acrescentar algumas observações e contra-argumentos à resposta de jfriend00. (principalmente apenas minhas opiniões baseadas no meu instinto)
Não - você NÃO deve vincular todos os manipuladores de eventos delegados ao objeto de documento. Esse é provavelmente o cenário com pior desempenho que você pode criar.
Primeiro, a delegação de eventos nem sempre torna seu código mais rápido. Em alguns casos, é vantajoso e, em alguns casos, não. Você deve usar a delegação de eventos quando realmente precisar da delegação de eventos e quando se beneficiar dela. Caso contrário, você deve vincular manipuladores de eventos diretamente aos objetos em que o evento acontece, pois isso geralmente será mais eficiente.
Embora seja verdade que o desempenho possa ser um pouco melhor se você apenas se registrar e realizar um evento para um único elemento, acredito que ele não compensa os benefícios de escalabilidade que a delegação traz. Também acredito que os navegadores estão lidando com isso de maneira cada vez mais eficiente, embora não tenha provas disso. Na minha opinião, a delegação de eventos é o caminho a seguir!
Segundo, você NÃO deve vincular todos os eventos delegados no nível do documento. É exatamente por isso que .live () foi descontinuado porque isso é muito ineficiente quando você tem muitos eventos vinculados dessa maneira. Para manipulação de eventos delegados, é MUITO mais eficiente vinculá-los ao pai mais próximo que não é dinâmico.
Eu meio que concordo com isso. Se você tem 100% de certeza de que um evento ocorrerá apenas dentro de um contêiner, faz sentido vincular o evento a esse contêiner, mas eu ainda argumentaria contra a vinculação de eventos diretamente ao elemento acionador.
Terceiro, nem todos os eventos funcionam ou todos os problemas podem ser resolvidos com a delegação. Por exemplo, se você deseja interceptar eventos-chave em um controle de entrada e impedir que chaves inválidas sejam inseridas no controle de entrada, não é possível fazer isso com a manipulação de eventos delegados porque, quando o evento chegar ao manipulador delegado, ele já estará foi processado pelo controle de entrada e é tarde demais para influenciar esse comportamento.
Isto simplesmente não é verdade. Por favor, veja este códigoPen: https://codepen.io/pwkip/pen/jObGmjq
document.addEventListener('keypress', (e) => {
e.preventDefault();
});
Ele ilustra como você pode impedir que um usuário digite digitando o evento de pressionamento de tecla no documento.
Aqui estão os momentos em que a delegação de eventos é necessária ou vantajosa:
Quando os objetos nos quais você está capturando eventos são criados / removidos dinamicamente e você ainda deseja capturar eventos neles, sem precisar religar explicitamente os manipuladores de eventos toda vez que cria um novo. Quando você tem muitos objetos que desejam exatamente o mesmo manipulador de eventos (onde lotes é pelo menos centenas). Nesse caso, pode ser mais eficiente no momento da configuração vincular um manipulador de eventos delegados em vez de centenas ou mais manipuladores de eventos diretos. Observe que o tratamento de eventos delegados é sempre menos eficiente em tempo de execução do que os manipuladores diretos de eventos.
Gostaria de responder com esta citação de https://ehsangazar.com/optimizing-javascript-event-listeners-for-performance-e28406ad406c
Event delegation promotes binding as few DOM event handlers as possible, since each event handler requires memory. For example, let’s say that we have an HTML unordered list we want to bind event handlers to. Instead of binding a click event handler for each list item (which may be hundreds for all we know), we bind one click handler to the parent unordered list itself.
Além disso, pesquisar no Google performance cost of event delegation google
retorna mais resultados em favor da delegação de eventos.
Quando você está tentando capturar (em um nível mais alto no seu documento) eventos que ocorrem em qualquer elemento do documento. Quando o seu design está usando explicitamente o evento bubbling e stopPropagation () para resolver algum problema ou recurso em sua página. Para entender um pouco mais, é preciso entender como os manipuladores de eventos delegados do jQuery funcionam. Quando você chama algo assim:
$ ("# myParent"). on ('clique', 'button.actionButton', myFn); Ele instala um manipulador de eventos jQuery genérico no objeto #myParent. Quando um evento de clique é associado a esse manipulador de eventos delegados, o jQuery precisa percorrer a lista de manipuladores de eventos delegados anexados a esse objeto e verificar se o elemento de origem do evento corresponde a algum dos seletores nos manipuladores de eventos delegados.
Como os seletores podem estar bastante envolvidos, isso significa que o jQuery precisa analisar cada seletor e compará-lo às características do destino do evento original para ver se ele corresponde a cada seletor. Esta não é uma operação barata. Não é grande coisa se houver apenas um deles, mas se você colocar todos os seus seletores no objeto de documento e houver centenas de seletores para comparar com cada evento com bolhas, isso poderá prejudicar seriamente o desempenho da manipulação de eventos.
Por esse motivo, você deseja configurar seus manipuladores de eventos delegados para que um manipulador de eventos delegados fique o mais próximo possível do objeto de destino. Isso significa que menos eventos serão exibidos em cada manipulador de eventos delegados, melhorando assim o desempenho. Colocar todos os eventos delegados no objeto de documento é o pior desempenho possível, porque todos os eventos com bolhas precisam passar por todos os manipuladores de eventos delegados e serem avaliados com relação a todos os possíveis seletores de eventos delegados. É exatamente por isso que .live () foi descontinuado, porque foi isso que .live () fez e provou ser muito ineficiente.
Onde isso está documentado? Se isso for verdade, o jQuery parece estar lidando com a delegação de uma maneira muito ineficiente, e meus contra-argumentos devem ser aplicados apenas ao JS vanilla.
Ainda assim: eu gostaria de encontrar uma fonte oficial que apoie essa reivindicação.
:: EDIT ::
Parece que o jQuery está realmente fazendo bolhas de eventos de uma maneira muito ineficiente (porque eles suportam o IE8)
https://api.jquery.com/on/#event-performance
Portanto, a maioria dos meus argumentos aqui é válida apenas para JS vanilla e navegadores modernos.