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

JSfiddle jsfiddleI would like to use this concept of event delegation on each name spaced event. Appern

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

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());
});
Share Improve this question edited Aug 14, 2013 at 11:40 nirazul 3,9654 gold badges29 silver badges48 bronze badges asked Aug 14, 2013 at 9:48 John AbrahamJohn Abraham 18.8k36 gold badges132 silver badges240 bronze badges 10
  • +1 for even attempting it like that :) Do you have a JSFiddle for this? – iCollect.it Ltd Commented Aug 14, 2013 at 9:56
  • You have assigned the events to the selectors (i.e. "li") instead of the event type. That just looks wrong pared to the multi-event examples. – iCollect.it Ltd Commented Aug 14, 2013 at 9:58
  • I know the li is wrong .. .wondering how to make it right lol – John Abraham Commented Aug 14, 2013 at 9:58
  • Added a JSFiddle with answer so you can play with options, but basically do not overplicate your code for the sake of a slight/negligible speed improvement. K.I.S.S. is the way to go. – iCollect.it Ltd Commented Aug 14, 2013 at 10:10
  • I dont see the jsfiddles link... I totally understand the K.I.S.S mentality but learning these things make typically improve my structure and overall understanding of jquery/javascript (seeing that I'm still pretty novice) I just want to see the limitation. More of an excerise then a practical use. – John Abraham Commented Aug 14, 2013 at 10:12
 |  Show 5 more ments

5 Answers 5

Reset to default 3

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

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

The each answer given will not be more efficient than using the .big-ul li selector. My theory being that a basic on() selector runs against the selector once and connects the event immediately whereas the deferred on() with selector runs the selectors each time the events occur (to find the matching elements).

You might as well do it this way and keep it simple:

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

http://jsfiddle/AzQBR/1/

I am happy to be overruled about the speed of deferred on() pared to non-deferred on() calls if someone can run performance stats.

Having looked over all the answers again (including my original one), I would remend simply connecting each event separately using the deferred on() syntax:

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

All the other solutions over-plicate the code. This is about a straight forward as you can get.

JSFiddle http://jsfiddle/AzQBR/2/

It is possible guys! But you wrote it in wrong way! Try this :

$(document).ready(function(){
$(document).on({
    mouseenter: function(){
        $(this).css("background-color", "lightgray");
    },  
    mouseleave: function(){
        $(this).css("background-color", "lightblue");
    }, 
    click: function(){
        $(this).css("background-color", "yellow");
    }  
},'p');

});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745320333a4622415.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信