Question

Lately I've been studying a lot of javascript samples, both with/without libraries, jQuery to mention one.

As an old JavaScript developer, I learned early to make use of unobtrusive javascript where one were adding mouse click events to a global handler using document.onclick = mylib.document_onclick;

Then, by tagging any element with a custom attribute/property/expando, I been able to deal with all kinds of functions in a very simple way.

//  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 ......
        }
    }
},

Today I see a lot solutions where the event is bound/attached straight to a specific element.

It appears to quikly become a long list of handlers to be added, together with individual functions and class names tied/added.

//  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>');
    });

});

Referring to the way setting up handlers, is one approach better than the other, and if so, which one is and why?

Was it helpful?

Solution

The problem with your approach is that you are replacing the browser's dispatching mechanism with your own dispatching mechanism. The browser's dispatching is not bad enough to be replaced, and is certainly better than yours:

  • The browser's mechanism is native to the browser, and therefore faster than your implementation in interpreted language(JavaScript).

  • Your mechanism uses a big switch statement, which also makes it slower.

  • To add more handlers to your mechanism you need to edit the giant dispatching function. To add handlers to the browser's mechanism you simply need to set the elements' attributes, which you can do from wherever appropriate - much better than a single gigantic function.

The example you've given, while seems to be very popular nowadays, is not good either since it creates massive amounts of boilerplate code duplication. I simply fail to see the benefit of searching for elements by their unique id to attach handlers to them over writing the handler directly in the element's HTML(the function call! not the implementation!).

Another popular approach is to use the class attribute instead of id - which I believe to be even worse. Why go through all the trouble of separating the logic(JS) from the document structure(HTML), just to couple it with the style(CSS)?

What I usually do is use JQuery's convenient syntax of searching-by-css-selector and attaching-anonymous-function-as-event-handler to "extend HTML" - similar to what you do but without a gloabl handler, but with separate handlers for each type of action:

//  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;
        });
});

That way, I can create separate handlers instead of you giant switch statement, but just like you I can use the elements' attribute to assign handlers to elements dynamically.

Licensed under: CC-BY-SA with attribution
scroll top