如何使用委托事件,命名空间和附加多个事件处理程序

时间:2013-08-14 09:48:29

标签: javascript jquery events event-bubbling

JSfiddle jsfiddle

我想在每个名称间隔事件上使用event delegation的这个概念。 Appernetly它比.big-ul li更优化。遗憾的是,在使用命名空间或尝试使用普通对象同时附加多个事件处理程序时,我无法找到使其正常工作的正确语法?

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

来自jquery网站的事件委派示例

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

5 个答案:

答案 0 :(得分:3)

您无法将多个事件附加到多个此类功能。你可以做的是在包含所有需要的信息的对象上使用each函数。您甚至可以将名称空间名称(haha)存储在单独的变量中:

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

与已接受的解决方案相比的优势:

  1. 这是一个更加灵活的解决方案,因为您可以跨模块发送events - 对象或使用单个函数动态绑定事件,当您始终使用相同的event - 对象结构时。
  2. 您可以从一个根对象委派给不同的子节点,而不仅仅是一个。
  3. 示例

    /* 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);  
        }
    }
    

答案 1 :(得分:3)

这样的事情怎么样?

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

这不起作用吗?

修改 如果你愿意的话,你也可以用switch语句替换mutiple if语句......它可能会提供更好的性能(如果你担心的话)。

$(".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 已更新,因此jsfiddle将根据@Nirazul所说的内容工作。 Example on jsFiddle

答案 2 :(得分:2)

给出的each答案不会比使用.big-ul li选择器更有效。我的理论是基本的on()选择器对选择器运行一次并立即连接事件,而带有选择器的延迟on()在每次事件发生时运行选择器(找到匹配的元素)。

你也可以这样做,并保持简单:

$(".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.net/AzQBR/1/

如果有人可以运行性能统计数据,我很高兴被推翻onferred()与非延迟on()调用相比的速度。

答案 3 :(得分:1)

再次查看了所有答案(包括我的原始答案),我建议您使用延迟on()语法单独连接每个事件:

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

所有其他解决方案使代码过于复杂。这是你可以得到的直接前进。

JSFiddle http://jsfiddle.net/AzQBR/2/

答案 4 :(得分:1)

有可能是伙计们!但是你用错误的方式写了它!试试这个:

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

});