Nota: apenas traduzi o texto abaixo e postei aqui.
Hoje, veremos abordagens para usar event delegation com múltiplos seletores.
Como isso funciona
Se você não está familiarizado com a abordagem, veja como funciona. Em vez de attaching events a elementos específicos, você "listen" esse event em um parent element (geralmente o document ou window).
Qualquer event desse tipo que aconteça dentro do parent element aparece e você pode filtrar aqueles que não match ao element que você está procurando.
document.addEventListener('click', function (event) {
    // Verifica a classe .click-me
    // Se o elemento clicado não possui ela, não faça nada
    if (!event.target.matches('.click-me')) return;
    // O código que você quer executar vai aqui
});
Se você estiver "listen" events em mais de um element com o mesmo seletor, essa abordagem é realmente melhor para desempenho porque usa menos memória no navegador.
Múltiplos seletores
Quando compartilho essa abordagem, muitas vezes os alunos me perguntam como implementá-la quando você precisa "listen" o mesmo tipo de event para vários seletores diferentes e fazer coisas diferentes com base no seletor que o elemento possui.
Por exemplo, digamos que você tenha botões mostrar/ocultar conteúdo que possuem uma classe .show-me e outro conjunto de botões com a classe .save que salva o conteúdo de um form para reutilização posterior.
Como você analisa quais ações serão executadas com base no seletor?
Opção 1: separe event listeners
A abordagem mais óbvia é usar dois event listeners separados, um para cada seletor.
document.addEventListener('click', function (event) {
    if (!event.target.matches('.show-me')) return;
    // Revele o conteúdo escondido...
});
document.addEventListener('click', function (event) {
    if (!event.target.matches('.save')) return;
    // Salve o conteúdo do form...
});
Essa abordagem funciona bem se seus scripts forem mantidos em arquivos modulares separados.
Embora você esteja usando dois event listeners em vez de um, isso ainda é muito melhor para o desempenho do que "attaching" um listener a cada botão correspondente.
Opção 2: if...else
Se os dois trechos de código estiverem no mesmo arquivo, você poderá combiná-los em um único event listener e usar uma instrução if...else if.
document.addEventListener('click', function (event) {
    if (event.target.matches('.show-me')) {
        // Revele o conteúdo escondido...
    } else if (event.target.matches('.save')) {
        // Salve o conteúdo do form...
    }
});
Isso proporciona um pequeno aumento de desempenho.
Opção 3: if e return
Muitas pessoas acham as instruções if...else if difíceis de manejar, especialmente se você tiver mais do que apenas algumas verificações. Eles podem crescer rapidamente e sair fora de controle.
Por esse motivo, prefiro usar instruções if sequenciais, com "returns" entre chaves para encerrar a function quando ocorrer um match.
document.addEventListener('click', function (event) {
    if (event.target.matches('.show-me')) {
        // Revele o conteúdo escondido...
        return;
    }
    if (event.target.matches('.save')) {
        // Salve o conteúdo do form...
        return;
    }
});
Essa abordagem é, para mim, mais fácil de ler. Isso também significa que posso movimentar minhas verificações sem me preocupar em quebrar nada.
Opção 4: handler functions
Se você gosta de programação funcional, essa abordagem fornece uma estrutura interessante.
Dentro do event listener callback, você chama handler functions separadas para cada seletor e passa o event object. Em cada handler function, você executa a verificação do seletor e executa o código de acordo.
var showMe = function (event) {
    if (!event.target.matches('.show-me')) return;
    // Revele o conteúdo escondido...
};
var saveMe = function (event) {
    if (!event.target.matches('.save')) return;
    // Salve o conteúdo do form...
};
document.addEventListener('click', function (event) {
    showMe(event);
    saveMe(event);
});
Essa abordagem fornece um bom equilíbrio entre desempenho e capacidade de manutenção.
O desempenho é um pouco menor do que as opções 2 e 3, porque a function saveMe() será executada mesmo se showMe() encontrar um match (as outras duas abordagens param assim que um match é encontrado). Mas ainda é melhor do que ter event listeners separados e fornece uma estrutura de código limpa e legível.
Qual abordagem você deve usar?
Em última análise, depende do seu projeto.
Eu uso muito a opção 1, porque costumo manter meus scripts em arquivos modulares. Mas quando o código está todo em um arquivo, a opção 4 é minha favorita.
Sugestão (atualizado):
Através da execução de Array.prototype.some da lista das handler functions, você pode executar somente até a primeira que retorne true, desde de que todas elas retornem isso (ou undefined no caso negativo) durante as verificações.
var showMe = function (event) {
    if (!event.target.matches('.show-me')) return;
    // Revele o conteúdo escondido...
    return true;
};
var saveMe = function (event) {
    if (!event.target.matches('.save')) return;
    // Salve o conteúdo do form...
    return true;
};
var otherLogic1 = function (event) {
    // a verificação negativa
    // a lógica
    return true;
}
var otherLogic2 = function (event) {
    // a verificação negativa
    // a lógica
    return true;
}
document.addEventListener('click', function (event) {
    [showMe, saveMe, otherLogic1, otherLogic2].some(
        handler => Boolean(handler(event))
    );
});
Array.prototype.some interrompe sua iteração interna quando a primeira execução da sua callback function retornar true.
Fonte
Newsletter de Go Make Things
              
    
Top comments (0)