Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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());
});
like image 537
Armeen Harwood Avatar asked Dec 25 '22 22:12

Armeen Harwood


2 Answers

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);  
    }
}
like image 59
nirazul Avatar answered Dec 28 '22 11:12

nirazul


how about something like this?

$(".big-ul").on("click.namespace mouseenter.namespace mouseleave.namespace", "li", function(event){
    var eventMatch = event.handleObj.origType + "." + event.handleObj.namespace;

    if(eventMatch == "click.namespace"){
        $(this).toggleClass("active");
    }
    if(eventMatch == "mouseenter.namespace"){
        $(this).addClass("inside");
    }
    if(eventMatch == "mouseleave.namespace"){
        $(this).removeClass("inside");
    }
});

would that not work?

EDIT you could also replace the mutiple if statements with a switch statement if you preferred... it would probably give better performance too (if you are worried about that).

$(".big-ul").on("click.namespace mouseenter.namespace mouseleave.namespace", "li", function(event){

    var eventMatch = event.handleObj.origType + "." + event.handleObj.namespace;

    switch(eventMatch){
        case "click.namespace":
            $(this).toggleClass("active");
        break;
        case "mouseenter.namespace":
            $(this).addClass("inside");
        break;
        case "mouseleave.namespace":
            $(this).removeClass("inside");
        break;
    }
});

EDIT2 updated so jsfiddle will work based on what @Nirazul said. Example on jsFiddle

like image 30
Jake Aitchison Avatar answered Dec 28 '22 11:12

Jake Aitchison