Manipuladores de eventos de objetos globais vs individuais

5

Ultimamente tenho estudado muitos exemplos de javascript, ambos com / sem bibliotecas, jQuery para mencionar um.

Como um antigo desenvolvedor de JavaScript, aprendi desde cedo a usar o javascript discreto em que um deles adicionava eventos de clique do mouse a um manipulador global usando document.onclick = mylib.document_onclick;

Então, ao marcar qualquer elemento com um atributo personalizado / propriedade / expando, eu pude lidar com todos os tipos de funções em um maneira muito simples.

//  HTML

<div class='menulink logout' data-mc='logout'> Logout </div>
<a class='menulink' data-mc='ajax' data-target='main-content-div' href='page/'>Start page 1</a>
<a class='menulink' data-mc='ajax' data-target='main-content-div' href='page/'>Start page 2</a>


// JS

document_onclick: function (e) {
    e = getEvObj(e);                             // custom method to get event object
    var evSrcTag = getSrcObj(e);                 // custom method to get source element

    //mouseclick
    if (evSrcTag.getAttribute('data-mc') != undefined) {
        switch (evSrcTag.getAttribute('data-mc')) {

            case 'logout':
                if (!confirm(myconfig.msg['asklogout'])) {
                    return cancelEv(e);          // custom method to cancel the event
                }
                break;

            case 'ajax':
                //process ajax request as javascript is available, cancel default event (href)

            //case ......
        }
    }
},

Hoje vejo muitas soluções em que o evento é vinculado / anexado diretamente a um elemento específico.

Parece ser uma lista longa de manipuladores a serem adicionados, juntamente com funções individuais e nomes de classes vinculados / adicionados.

//  HTML
<a id="anchor1" href="#">create link dynamically</a>
<a id="anchor2" href="#">create link dynamically</a>
<a id="anchor3" href="#">create link dynamically</a>


//  JS
$(function(){

    $("#anchor1").click( function() {
        $("#anchor1").append('<a class="myclass" href="page/test1">test1</a>');
    });

    $("#anchor2").click( function() {
        $("#anchor2").append('<a class="myclass" href="page/test2">test2</a>');
    });

    $("#anchor3").click( function() {
        $("#anchor3").append('<a class="myclass" href="page/test3">test3</a>');
    });

});

Referindo-se à maneira de configurar manipuladores, uma abordagem é melhor do que a outra e, em caso afirmativo, qual é e por quê?

    
por LGSon 05.03.2014 / 16:58
fonte

1 resposta

2

O problema com a sua abordagem é que você está substituindo o mecanismo de despacho do navegador por seu próprio mecanismo de despacho. O despacho do navegador não é ruim o suficiente para ser substituído e é certamente melhor que o seu:

  • O mecanismo do navegador é nativo ao navegador e, portanto, mais rápido do que sua implementação na linguagem interpretada (JavaScript).

  • Seu mecanismo usa uma grande instrução switch, o que também a torna mais lenta.

  • Para adicionar mais manipuladores ao seu mecanismo, você precisa editar a função de dispatching gigante. Para adicionar manipuladores ao mecanismo do navegador, você simplesmente precisa definir os atributos dos elementos, o que pode ser feito de qualquer lugar - muito melhor do que uma única função gigantesca.

O exemplo que você deu, embora pareça ser muito popular hoje em dia, também não é bom, pois cria uma enorme quantidade de duplicação de código clichê. Eu simplesmente não consigo ver o benefício de procurar por elementos pelo seu ID único para anexar manipuladores a eles ao escrever o manipulador diretamente no HTML do elemento (a chamada de função! Não a implementação!).

Outra abordagem popular é usar o atributo class em vez de id - que acredito ser ainda pior. Por que passar por todo o trabalho de separar a lógica (JS) da estrutura do documento (HTML), apenas para acoplá-la ao estilo (CSS)?

O que eu costumo fazer é usar a sintaxe conveniente do JQuery de procurar por css-seletor e anexar-anônimo-função-como-manipulador de eventos para "estender HTML" - semelhante ao que você faz, mas sem um manipulador gloabl, mas com manipuladores separados para cada tipo de ação:

//  HTML

<div class='menulink logout' data-mc='logout'> Logout </div>
<a class='menulink' data-mc='ajax' data-target='main-content-div' href='page/'>Start page 1</a>
<a class='menulink' data-mc='ajax' data-target='main-content-div' href='page/'>Start page 2</a>


// JS

$(function(){
        $('[data-mc=logout]').click(function(){
                if (!confirm(myconfig.msg['asklogout'])) {
                    return false;
                }
        });

        $('[data-mc=ajax]').click(function(){
                var target=$(this).data('target'); //retrieve data-target of the clicked tag
                return false;
        });
});

Dessa forma, posso criar manipuladores separados em vez de sua declaração switch gigante, mas, assim como você, posso usar o atributo elements para atribuir manipuladores a elementos dinamicamente.

    
por 05.03.2014 / 17:38
fonte