4

JSfiddle _

我想在每个名称空间事件上使用这个事件委托的概念。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());
});
4

5 回答 5

3

您不能像这样将多个事件附加到多个函数。您可以做的是each在包含所有所需信息的对象上使用函数。您甚至可以将您的命名空间名称(哈哈)存储在一个单独的变量中:

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

示例

/* 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);  
    }
}
于 2013-08-14T10:03:15.433 回答
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 语句替换多个 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

于 2013-08-14T10:07:50.277 回答
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/

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

于 2013-08-14T10:08:18.987 回答
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/

于 2013-08-14T15:30:21.107 回答
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');

});

于 2018-03-16T07:02:12.093 回答