Event Organization

I bind a one-click event to a large container using jquery (event delegation).

I have many different elements inside this container that can be clicked.

The problem I'm dealing with is that if I have 20 elements that can be clicked, I need to do if if else block x 20 in the container in the click handler. Is there any way to make this cleaner? For instance:

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

and etc.

+6
source share
6 answers

The first thing that comes to mind is to use a loop:

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

Create an object with functions

It's a bit late to play with this, but you should consider organizing your code like this.

If you have 20 unique actions for your widgets, you will go to all this code. Try reusing shared code by creating functions. Create a structure like this:

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

Simplified execution

Then, from your click handler, just call the function as follows:

 handleOnClick : function(event) { actions.call(event) } 
+2
source

jQuery offers this functionality out of the box:

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

I recently wrote a library to extract it if you are not using jQuery. It is called a gator. You can see examples / documentation at: http://craig.is/riding/gators

You can do something like

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

Both jQuery and Gator bind a single click event to a container element and handle events inside.

+1
source

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
source

Perhaps this is what you are looking for. There are many ways to do this.

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

Here is js

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

How about using delegate ?

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

Source: https://habr.com/ru/post/885548/


All Articles