Search code examples
javascriptjqueryeventsevent-bubbling

How to use delegated-events, name spaces and attaching multiple event handlers


JSfiddle jsfiddle

I would like to use this concept of event delegation on each name spaced event. Appernetly it is more optimized than .big-ul li. I unfortunately cannot find the proper syntax to make it work while using namespaces or while trying to attach multiple event handlers simultaneously using a plain object?

$(".big-ul").on({
  "click.namespace", "li": function(event){
    $(this).toggleClass("active");
  },
  "mouseenter.namespace" , "li": function(event){
    $(this).addClass("inside");
  },
  "mouseleave.namespace", "li": function(event){
    $(this).removeClass("inside");
  }
});

example of event delegation from jquery's site

$("#dataTable tbody").on("click", "tr", function(event){
  alert($(this).text());
});

Solution

  • You can't attach multiple events to multiple functions like that. What you could do is using an each function on an object containing all the needed infos. You could even store your namespace-name (haha) in a separate variable:

    Example on jsFiddle

    var $root = $(".big-ul");
    var namespace = 'namespace';
    var events = [
        {
            event: "click"+"."+namespace, 
            delegate: "li",
            fn: function(event){
                $(this).toggleClass("active");
            }
        },
        {
            event: "mouseenter"+"."+namespace, 
            delegate: "li",
            fn: function(event){
                $(this).addClass("inside");
            }
        },
        {
            event: "mouseleave"+"."+namespace, 
            delegate: "li",
            fn: function(event){
                $(this).removeClass("inside");
            }
        }
    ]
    
    for(i=0;i<events.length;i++){
        $root.on(events[i].event, events[i].delegate, events[i].fn);  
    }
    

    The advantage compared with the accepted solution:

    1. It's a far more flexible solution as you could send the events-Object across modules or dynamically bind events with one single function, when you always use the same event-Object structure.
    2. You can delegate from one root object to different child nodes, not only one.

    Example:

    /* events array*/
    var events = [
        {
            root: "root-query-string",
            event: "eventname",
            delegate: "delegate-query-string",
            fn: function
        }
    ]
    
    /* dynamic batch bind function */
    function batchBind(events) {
        for(i=0; i<events.length; i++){
            $(el.root).on(events[i].event, events[i].delegate, events[i].fn);  
        }
    }