JavaScript事件委派代码组织

JavaScript事件委派代码组织,javascript,jquery,html,javascript-events,Javascript,Jquery,Html,Javascript Events,我正在使用jquery(事件委派)将一个单击事件绑定到一个大型容器 我有许多不同的项目,在该容器中是可点击的 我要处理的问题是,如果我有20个可单击的项目,我需要在容器中单击处理程序时执行if-else块x20。有没有办法让这个更干净?例如: attachClickEvent:function(){ $(".container").click($.proxy(this.handleOnClick,this)); }, handleOnClick:function(event){

我正在使用jquery(事件委派)将一个单击事件绑定到一个大型容器

我有许多不同的项目,在该容器中是可点击的

我要处理的问题是,如果我有20个可单击的项目,我需要在容器中单击处理程序时执行if-else块x20。有没有办法让这个更干净?例如:

attachClickEvent:function(){
    $(".container").click($.proxy(this.handleOnClick,this));
},
handleOnClick:function(event){
     var $target = $(event.target);
     if($target.closest(".widget1").length >0){
         //handle widget 1 interaction
     }else if($target.closest(".widget2").length >0){
         //handle widget 2 interaction
     }else if($target.closest(".widget3").length >0){
         //handle widget 3 interaction
     }else if($target.closest(".widget4").length >0){
         //handle widget 4 interaction
     }else if($target.closest(".widget5").length >0){
         //handle widget 5 interaction
     }
}
等等。

HTML

<div class="container">
 <div id="cont1"></div>
 <div id="cont2"></div>
 <div id="cont3"></div>
 <div id="cont4"></div>
 <div id="cont5"></div>
 <div id="cont6"></div>
.
.
.

</div>

这可能是你正在寻找的东西。有很多不同的方法可以做到这一点

<div id="widgetcontainer">
    <div id="widget1">A</div>
    <div id="widget2">B</div>
    <div id="widget3">C</div>
    <div id="widget4">D</div>
    <div id="widget5">E</div>  
</div>

A.
B
C
D
E
这是JS

function someAction() {
    alert("Hey");
}


$(function() {
    var wc = $("#widgetcontainer div");
    for (var i = 0; i < wc.length; i++) {
        $(wc[i]).click(function() {
            someAction();
        });
    }
});
函数someAction(){
警惕(“嘿”);
}
$(函数(){
var wc=$(“#widgetcontainer div”);
对于(变量i=0;i
首先想到的是使用循环:

var handlers = {
  "widget1": function(event, candidate){},
  "widget2": function(event, candidate){}
}

$.each(handlers, function(cssClass,handler){
  var sel = '.'+cssClass;
  var candidate = target.closest(sel);
  if(candidate.length > 0) {
    handler(event, candidate);
    break;
  }
});

使用代理如何

$(".container").
    delegate(".widget1", "click", widget_1_handler).
    delegate(".widget2", "click", widget_2_handler)
;

使用函数创建对象

这个游戏有点晚了,但是你应该考虑像这样组织你的代码。

如果您的小部件有20个独特的操作,那么您将看到所有这些代码。尝试通过创建函数重用公共代码。制作如下结构:

var actions = {
    'widget1' : function(event) {
        // handle widget 1 interaction
    },
    'widget2' : function(event) {
        // handle widget 2 interaction
    },
    'widget3' : function(event) {
        // handle widget 3 interaction
    },
    call : function(event) {
        var prefix = "widget",
            widget = $(event.target).closest('[class^="'+prefix+'"]'),
            classN;
        if(widget.length) {
            classN = widget.attr('class').replace(new RegExp('.*('+prefix+'\\d*).*$'), '$1');
            if(classN in this) {
                this[classN](event);
            }
        }
    }
};
handleOnClick : function(event) {
    actions.call(event)
}
简化执行

然后,从单击处理程序中,只需按如下方式调用函数:

var actions = {
    'widget1' : function(event) {
        // handle widget 1 interaction
    },
    'widget2' : function(event) {
        // handle widget 2 interaction
    },
    'widget3' : function(event) {
        // handle widget 3 interaction
    },
    call : function(event) {
        var prefix = "widget",
            widget = $(event.target).closest('[class^="'+prefix+'"]'),
            classN;
        if(widget.length) {
            classN = widget.attr('class').replace(new RegExp('.*('+prefix+'\\d*).*$'), '$1');
            if(classN in this) {
                this[classN](event);
            }
        }
    }
};
handleOnClick : function(event) {
    actions.call(event)
}

jQuery提供了这种开箱即用的功能:

$('.container').on('click', '.widget1', function() {
    // handle widget 1 interaction
});

$('.container').on('click', '.widget2', function() {
    // handle widget 2 interaction
});
我最近编写了一个库,如果您不使用jQuery,就可以提取它。它叫盖特。您可以在以下位置查看示例/文档:

你可以这样做

Gator(container_element).on('click', '.widget1', function() {
    // handle widget 1 interaction
});

Gator(container_element).on('click', '.widget2', function() {
    // handle widget 2 interaction
});

jQuery和Gator都只将一个单击事件绑定到容器元素,并在内部处理事件分派。

这不再是事件委派,而是将一个事件绑定到每个div。此外,您仍在执行if/else x个div。这仍然不是事件委派。事件委派是将一个事件绑定到父节点,并侦听单击子节点时出现的事件。在这里,您将一个click事件绑定到每个div。使用target意味着您正在click处理程序中运行这个循环。这是不好的,因为您必须运行$(target).closest()可能超过20次才能找到匹配的属性。您还使用了
class
关键字,该关键字将在webkit中出现。@typeof:它正在单击处理程序中运行。。。他将委托给包含一组20个项的父元素,每个项都有特定的处理程序操作。因此,他需要遍历所有选择器,直到找到匹配项,然后调用相关的处理函数<代码>目标。最近的(sel)是他的测试。。。在每次迭代中都必须调用它,直到匹配为止——然后当匹配从循环中中断时。更改了变量名。。虽然这个wanst意味着工作代码。。。只是一个粗略的例子循环是不必要的,也不应该使用。@typeof:那么您将如何实现?我同意可能有更好的方法来测试,或者甚至可以用一个测试选择器来确定要调用哪个处理程序,但是他没有展示足够的代码来确定要调用什么,所以我按照他的要求做了具体的工作——如果需要的话,给出一个使用20条件的替代方案/else@prodigitalson看看我的答案。