-1
<html lang="en">
<head>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>

<div class="a" style='font-size:50'>a</div>
<div class="b" style='font-size:50'>b</div>
<div class="c" style='font-size:50'>c</div>

<script>
var classes = ['a', 'b', 'c'];
for (var i = 0; i < classes.length; i++) {
  $("."+classes[i]).mouseover(function() {
    console.log(i);
    console.log(classes[i]);
  });
}
</script>

</body>
</html>

This is the simplest reproduction of the issue I could create. When mouseovering the elements, there are two things wrong:

  1. log(i) always logs '3', which doesn't make sense because the loop ends at 2.
  2. classes[i] returns Undefined, even though I just defined it at the top of the script.
j08691
  • 204,283
  • 31
  • 260
  • 272
cas5nq
  • 413
  • 5
  • 11
  • When that function is executed, and it looks for `i`, where will it find it and what will its value be? – alex May 09 '16 at 15:02
  • The variable i becomes a 3 before the loop ends. Because this is javascript (which can act a little weird sometimes) unless you reassign i, it will keep that value even though it is out of scope once the loop ends. Thus when the event actually fires, i = 3 so it prints 3. But the array only goes to 2 so you get undefined for classes[3]. If you want to know the class on fire, use $(this).prop('class'). – nurdyguy May 09 '16 at 15:12

1 Answers1

1

Use the .each() and .filter() extensions instead. This will work to fix a lot of issues as you don't have to use an integer. to do this, see the below code:

$('div').filter(function() {
  return $(this).hasClass('a') || $(this).hasClass('b') || $(this).hasClass('c'); //gets any divs with the class 'a', 'b', or 'c'
}).each(function(){ // performs a function on each of these divs
  console.log($(this).text()); // logs each divs inner text (change as required)
})
TechnicalTophat
  • 1,655
  • 1
  • 15
  • 37