HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMajor

Different way of writing multiple click functions

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
clickwritingwaydifferentmultiplefunctions

Problem

I have the following .click() functions:

$('.tab').click(function(){
    $('.tab').removeClass('activeTab');
    $(this).addClass('activeTab');
});

$('.edit').click(function(){
    $(this).hide();
    $(this).next().show();
});

$('.cancel').click(function(){
    $(this).parent().hide();
    $(this).parent().prev().show();
});


Is it possible to combine these functions doing something like this?

Pseudocode:

$.click(function(){
    for $('.tab'){
        //do this
    }
    for $('.edit'){
        //do this
    }
    for $('.cancel'){
        //do this
    }
});


HTML:

Edit

    Cancel |
    Save 

Solution

First off, I'd rewrite the HTML to get rid of the javascript href attributes. I'd also use a data-action attribute for the action name. You can still use class to do the styling of course, but style is not behavior, so keep those things separate (i.e. the class might be action-button primary highlighted or something, but the action would still be save):

Edit

    Cancel |
    Save 


Code-wise, what each link has in common is that they should preventDefault so the links aren't "followed" when clicked. So at the very least, we'll need this:

$("a[data-action]").on("click", function (event) {
  event.preventDefault();
});


Then of course, there are the actions/behaviors themselves. I'd suggest putting the logic for each in an object, and expanding the generic click handler like so:

var actions = {
  edit:   function (event) { ... },
  cancel: function (event) { ... },
  save:   function (event) { ... }
};

$("a[data-action]").on("click", function (event) {
  var link = $(this),
      action = link.data("action");

  event.preventDefault();

  // If there's an action with the given name, call it
  if( typeof actions[action] === "function" ) {
    actions[action].call(this, event);
  }
});


Now you have a generic click handler, and an easily extensible list of actions. The action functions themselves behave exactly like normal jQuery event handlers (i.e. this will refer to the link clicked, and the first argument will be the event).

Code Snippets

<a href="#" data-action="edit">Edit</a>
<span class="controls">
    <a href="#" data-action="cancel">Cancel</a> |
    <a href="#" data-action="save">Save</a> 
</span>
$("a[data-action]").on("click", function (event) {
  event.preventDefault();
});
var actions = {
  edit:   function (event) { ... },
  cancel: function (event) { ... },
  save:   function (event) { ... }
};

$("a[data-action]").on("click", function (event) {
  var link = $(this),
      action = link.data("action");

  event.preventDefault();

  // If there's an action with the given name, call it
  if( typeof actions[action] === "function" ) {
    actions[action].call(this, event);
  }
});

Context

StackExchange Code Review Q#18160, answer score: 31

Revisions (0)

No revisions yet.