MonkeyBusiness
MonkeyBusiness

Reputation: 379

How do I bind JavaScript events to dynamic classes

I need to generate a background color change for all members of the same class when any member of that class has a mouseover.

Here's the JavaScript:

var array = ['abc','def','abc','xyz'];
var row;
var cell = [];
var rowClass = [];

for (var i = 0; i < array.length; i++){
    // Insert an empty <tr> element
    row = document.getElementById("myTable").insertRow(i+1);

    // Insert cells <td></td>
    for(var j = 0; j < 2; j++){
        cell[j] = row.insertCell(j);
    };
    
    // fill cells <td></td>
    cell[0].innerHTML = 'row ' + i;
    cell[1].innerHTML = array[i];
    cell[1].setAttribute("class", array[i]);
}
var k0 = 0;
rowClass[k0] = '.' + array[k0];
$(document).on('mouseover', rowClass[k0] ,function() {$(rowClass[k0]).css("background-color", "yellow");});
$(document).on('mouseout', rowClass[k0] ,function() {$(rowClass[k0]).css("background-color", "");});

var k1 = 1;
rowClass[k1] = '.' + array[k1]; 
$(document).on('mouseover', rowClass[k1] ,function() {$(rowClass[k1]).css("background-color", "yellow");});
$(document).on('mouseout', rowClass[k1] ,function() {$(rowClass[k1]).css("background-color", "");});

var k2 = 2;
rowClass[k2] = '.' + array[k2];
$(document).on('mouseover', rowClass[k2] ,function() {$(rowClass[k2]).css("background-color", "yellow");});
$(document).on('mouseout', rowClass[k2] ,function() {$(rowClass[k2]).css("background-color", "");});

var k3 = 3;
rowClass[k3] = '.' + array[k3];
$(document).on('mouseover', rowClass[k3] ,function() {$(rowClass[k3]).css("background-color", "yellow");});
$(document).on('mouseout', rowClass[k3] ,function() {$(rowClass[k3]).css("background-color", "");});

Here is a JSfiddle.

How do I replace the four explicit on statements hack with the proper code? After trying loops and various answers suggest on Stack Overflow, this is the best I could do just to get it to work.

Upvotes: 1

Views: 120

Answers (1)

robbmj
robbmj

Reputation: 16526

How do I replace the four explicit 'on' statements hack with the proper code? After trying loops ...

You can use a hover event instead of mouseover & mouseout. The reason why it probably did not work for you in a loop is because you were trying to use the index i in the event call back. Here is a fiddle that demonstrates the problem.

I think this is an arguably cleaner way to write the code. An explanation is in-lined with comments.

jQuery(function($) {
  var table = $('#myTable'),
      classes = ['abc', 'def', 'abc', 'xyz'];

  $.each(classes, function(index, class_name) {

    // create a table row and append 2 table cells to it
    var tr = $('<tr>').append([
      $('<td>', {
        'text': 'row ' + index
      }),
      $('<td>', {
        'text': class_name,
        'class': class_name
      }).hover(
        // replaces mouseover
        hoverEffect('yellow', class_name),
        // replaces mouseout
        hoverEffect('inherit', class_name)
      )
    ]);

    table.append(tr);
  });

  function hoverEffect(color, class_name) {
    // a function must be returned for the hover effect to work
    return function() {
      // this function closes over color and class_name
      $('.' + class_name).css('background-color', color);
    };
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<table id="myTable" width="100" cellpadding="3" border="1">
  <tr>
    <td>column1</td>
    <td>column2</td>
  </tr>
</table>

Upvotes: 1

Related Questions