0

Please say me why parameters transmited are wrong when I click on td case !

<!DOCTYPE html>
<html>
    <body>
        <table border=1>
          <tr>
            <td id="i_0">i_0</td>
            <td id="i_1">i_1</td>
            <td id="i_2">i_2</td>
            <td id="i_3">i_3</td>
            <td id="i_4">i_4</td>
            <td id="i_5">i_5</td>
          </tr>
        </table>

        <script>

          for (var i = 0; i < 6 ; i++) {  
             oc = document.getElementById("i_" + i);
             oc.onclick = function() { montre(oc.id , "t_" + i); };
          }

          function montre(bloc,item) {  
              alert(bloc + " | " + item);
          }

        </script>
    </body>
</html>

In the alert pop up I am waiting "i_0 | t_0" or "i_1 | t_1" or ... and I have always "i_5 | t_6", why ?

Where is my error ?

Oshadha
  • 546
  • 10
  • 25
  • 3
    that's a closure problem, you need to wrap your oc and i variable inside a closure, since the callback is done after the loop, you will access the last "i" and the last oc. – progysm Jun 20 '16 at 18:48
  • 1
    See http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – progysm Jun 20 '16 at 18:49
  • for (var i = 0; i < 6; i++) { (function(i) { var oc = document.getElementById("i_" + i); oc.onclick = function () { montre(oc.id, "t_" + i); }; })(i); } This will work for you. It uses a IIFE so it will retain each of the div a separate context. – Oshadha Jun 20 '16 at 19:20

1 Answers1

0

Try this

  function onClick(oc, index) {
     return function() {
        montre(oc.id , "t_" + i);
     }
  }
  for (var i = 0; i < 6 ; i++) 
  { 
     oc = document.getElementById("i_" + i);
     oc.onclick = onClick(oc, i);
  }

The variable oc, and i are changed for each iteration of the loop. Once the loop ends it equals the last value it was in the last iteration of the loop. Each click event shares the same variables so changing it in one place changes it for all click event handles. My suggested fix creates a new local variable for each click event handler.

  • It is good for firt argument, but not for the second . I have "i_0 | t_6" "i_1 | t_6" "i_2 | t_6" "i_3 | t_6" "i_4 | t_6" "i_5 | t_6" – top_nullus Jun 20 '16 at 19:17
  • I try also this for (var i = 0; i < 6 ; i++) { oc = document.getElementById("i_" + i); oc.addEventListener("click", montre(oc.id, "t_" + i)); } I have good alert pop up "i_0 | t_0" "i_1 | t_1" "i_2 | t_2" "i_3 | t_3" "i_4 | t_4" "i_5 | t_" but only when page is loaded, not on click – top_nullus Jun 20 '16 at 19:22
  • yes This question already has an answer here: JavaScript closure inside loops – simple practical example but it was asked 7 years ago and maybe something change. I an new in javascript and dom, and I do not speak english. sorry – top_nullus Jun 20 '16 at 19:36
  • OK it's good now ! I do not understand why, but I understand what I need to do. It is necessary to use a tank fonction to keep volatil value in itération beatween my fonction and construction. Thank you – top_nullus Jun 21 '16 at 05:44