asdf
asdf

Reputation: 1

Consolidating jQuery code

I have 30 buttons ranging from #p3-btn to #p30-btn that when clicked make .p3 div all the way up to .p30 div do a different effect. How do I consolidate this code so I don't have to literally copy and paste the code below 30 times and change the ids and classes?

  $('#p3-btn').click(function () {
    $('.p3').fadeIn().delay(2000).fadeOut();
  });

Cheers.

Upvotes: 0

Views: 48

Answers (3)

Rajesh
Rajesh

Reputation: 24915

You can use attribute selectors to achieve this.

function createDivs(len) {
  var $div = $('<div>');
  for (var i = 0; i < len; i++) {
    var prefix = 'p' + i;
    var $inner = $('<div>');
    $inner.attr('id', prefix + '-btn')
    var $p = $('<p>');
    $p.text(i).addClass(prefix);
    $inner.append($p);
    $div.append($inner);
  }
  return $div;
}
$(function() {
  $('.content').append(createDivs(30));

  $('[id^="p"][id$="-btn"]').on('click', function() {
    $(this).find('[class^=p]').fadeOut().delay(2000).fadeIn();
  });
})
[id$="-btn"] {
  width: 100%;
  border: 1px solid gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class='content' />

Upvotes: 0

GGO
GGO

Reputation: 2748

More simple that Shomz's anwser, you can use jquery selector :

$('button[id^="p"][id$="-btn"]').on("click", function() { 
    var id = $(this).attr("id").replace("-btn", "").replace("p", "");
    $('.p' + id).fadeIn().delay(2000).fadeOut();
});

Where $('button[id^="p"][id$="-btn"]') allow you to select the element type button which id starts with 'p' and ends with '-btn'.

Upvotes: 0

Shomz
Shomz

Reputation: 37701

This is a good demonstration of DRY (Don't Repeat Yourself) concept in programming. One of the way to tackle it is to make a function with the ID parameter which you will use to refer to the id of the element and the class of the other element, for example:

function attachClick(id){
  $('#' + id + '-btn').click(function () {
     $('.' + id).fadeIn().delay(2000).fadeOut();
  });
}

Then just call the function (say, from a for-loop) like this:

attachClick('p30');

While the example above would be a 1-to-1 match with your existing code, an even better approach would be to find a relation between each button and the element it affects so that way you'd avoid attaching a listener to each button individually, but rather attach one listener to a parent element and let the event handler function take care of the rest. However, without seeing your markup, I can't tell you whether you can do this without rewriting it or not. For example, that would be trivial to implement if you had markup like this:

<div class="container">
  <button>Button</button>
  <div>Div to be affected</div>
</div>

Upvotes: 1

Related Questions