5

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?

2

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.

  • +1 Wonderful, and behind the scenes, written in pure JavaScript, the jQuery translates to: element.onclick = function() {}, right? – LGSon Mar 5 '14 at 17:01
  • It's a bit more complex than that, since JQuery extends the dispatching mechanism to support multiple event handlers per element. – Idan Arye Mar 5 '14 at 18:13
  • Can you say/show how it would look written in JavaScript? .. or do you have some link showing how to extend the dispatching mechanism? – LGSon Mar 5 '14 at 18:16
  • And if you have time, I would appreciate if you could take a peek at this question: programmers.stackexchange.com/questions/231381/… – LGSon Mar 5 '14 at 18:32
  • From a quick glance the the JQuery code, it looks like they register handlers to elements, and those handlers receive the events and delegate them to the handlers you supply. – Idan Arye Mar 5 '14 at 21:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.