2011-04-09 71 views
6

我使用jquery(事件代理)将一个单击事件绑定到一个大容器。JavaScript事件代理组织代码

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

我正在处理的问题是,如果我有20个可点击的项目,我需要在点击处理程序的容器上做一个if else块x 20。有没有办法让这个更清洁? E.g:

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

回答

2

第一件事:

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

这也是我的想法,谢谢。 – Abadaba 2011-04-09 05:25:36

+0

您使用的目标意味着您正在点击处理程序中运行此循环。这是不好的,因为您必须运行$(target).closest()潜在的20多次才能找到匹配的属性。您还使用'class'关键字,它将在webkit中禁用。 – typeof 2011-04-09 18:44:24

+0

@typeof:它在click处理程序中运行......他正在委托给包含一组20个项目的父元素,每个项目都有特定的处理程序操作。因此,他需要遍历所有选择器,直到他得到一个匹配,然后调用相关的处理函数。 'target.closest(sel)'是他的测试......因为它必须在每次迭代中调用,直到匹配 - 然后当匹配突破循环。更改变量名称..虽然这wanish意味着工作代码...只是一个粗略的例子 – prodigitalson 2011-04-09 19:12:59

0

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> 

jQuery的

$(".container").find("div").click(function(){ 
id = $(this).attr("id"); 
if(id=="cont1"){ 
... 
} 
else if(id=="cont2"){ 
.. 
} 
.. 
else{ 
.. 
} 
}); 
+0

这不再是事件授权,您将事件绑定到每个div。此外,你仍然在做一个if/else x数量的div。 – Abadaba 2011-04-09 04:51:42

0

这也许就是你正在寻找的东西。有很多不同的方式来做到这一点。

<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> 

这里是JS

想到的是使用循环
function someAction() { 
    alert("Hey"); 
} 


$(function() { 
    var wc = $("#widgetcontainer div"); 
    for (var i = 0; i < wc.length; i++) { 
     $(wc[i]).click(function() { 
      someAction(); 
     }); 
    } 
}); 
+0

这仍然不是事件代表团。事件委托会将一个单一事件绑定到父级,并监听这些事件是由于子节点上的点击而引起的。在这里您将点击事件绑定到每个div。 – Abadaba 2011-04-09 05:25:17

0

如何使用delegate

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

创建的对象与功能

有点晚于这个游戏,但你应该考虑举办这样的代码。

如果您的窗口小部件有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) 
} 
1

jQuery提供这一功能的开箱:

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

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

我最近写了一个库来提取,如果你不使用jQuery。这就是所谓的鳄鱼。你可以看到在示例/文档: http://craig.is/riding/gators

你可以做这样的事情

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

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

两个jQuery和鳄鱼只能绑定一个单一的点击事件容器元素和处理内部调度的事件。