2011-04-09 69 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和鱷魚只能綁定一個單一的點擊事件容器元素和處理內部調度的事件。