最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin1浏览0评论

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

});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论