Предупреждение JavaScript некорректно работает с тегом div

#javascript #html #events #onclick

#javascript #HTML #Мероприятия #onclick

Вопрос:

В html есть 16 полей.

 <div id="box-container">
    <div class="box" data-coord="0:0" style="clear: left"></div> <div class="box" data-coord="0:1"></div> <div class="box" data-coord="0:2"></div> <div class="box" data-coord="0:3"></div>
    <div class="box" data-coord="1:0" style="clear: left"></div> <div class="box" data-coord="1:1"></div> <div class="box" data-coord="1:2"></div> <div class="box" data-coord="1:3"></div>
    <div class="box" data-coord="2:0" style="clear: left"></div> <div class="box" data-coord="2:1"></div> <div class="box" data-coord="2:2"></div> <div class="box" data-coord="2:3"></div>
    <div class="box" data-coord="3:0" style="clear: left"></div> <div class="box" data-coord="3:1"></div> <div class="box" data-coord="3:2"></div> <div class="box" data-coord="3:3"></div>
</div>
  

Я хочу написать js-код, который будет выполнять следующее:
Когда я нажимаю на любое поле, оно выдает предупреждение о номере заказа от 1 до 16.
Ниже приведен мой js-код:

 <script type="text/javascript">
    var boxArray = document.getElementsByClassName("box");
    for (var i = 0; i < boxArray.length; i  ) {
        boxArray[i].onclick = function () {
            var say = function (i) {
                alert(i);
            };
            say(i);
        }
    }
</script>
  

Но каждый раз оно предупреждает 16.
В чем проблема?
Не могли бы вы мне помочь, пожалуйста?

Ответ №1:

Используя классическое выражение функции IIFE: немедленного вызова, вы можете написать:

 var boxArray = document.getElementsByClassName("box");
for (var i = 0; i < boxArray.length; i  ) {
  boxArray[i].onclick = (function (i) {
    return function (e) {
      var say = function (i) {
        alert(i);
      };
      say(i);
    };
  })(i);
}  
 <div id="box-container">
    <div class="box" data-coord="0:0" style="clear: left">1</div> <div class="box" data-coord="0:1">2</div> <div class="box" data-coord="0:2">3</div> <div class="box" data-coord="0:3">4</div>
    <div class="box" data-coord="1:0" style="clear: left">5</div> <div class="box" data-coord="1:1">6</div> <div class="box" data-coord="1:2">7</div> <div class="box" data-coord="1:3">8</div>
    <div class="box" data-coord="2:0" style="clear: left">9</div> <div class="box" data-coord="2:1">10</div> <div class="box" data-coord="2:2">11</div> <div class="box" data-coord="2:3">12</div>
    <div class="box" data-coord="3:0" style="clear: left">13</div> <div class="box" data-coord="3:1">14</div> <div class="box" data-coord="3:2">15</div> <div class="box" data-coord="3:3">16</div>
</div>  

Ответ №2:

Это связано с областью действия javascript. i выходит за рамки цикла for, потому что вы использовали var , поэтому, когда вы это делаете alert(i) , оно принимает значение, которое i остается после цикла (поскольку цикл уже запущен).

Измените цикл for с

 for (var i = 0; i < boxArray.length; i  )
  

Для

 for (let i = 0; i < boxArray.length; i  )
  

И это должно решить вашу проблему.

Ответ №3:

Вы можете использовать addEventListener с локальной объявленной переменной, например, так

 var boxArray = document.getElementsByClassName("box");
for (var i = 0; i < boxArray.length; i  ) {
  boxArray[i].addEventListener('click', (function(e) {
    var num = i;
    return function() {
      alert(num);
    }
  })());
}  
 <div id="box-container">
  <div class="box" data-coord="0:0" style="clear: left">1</div>
  <div class="box" data-coord="0:1">2</div>
  <div class="box" data-coord="0:2">3</div>
  <div class="box" data-coord="0:3">4</div>
  <div class="box" data-coord="1:0" style="clear: left">5</div>
  <div class="box" data-coord="1:1">6</div>
  <div class="box" data-coord="1:2">7</div>
  <div class="box" data-coord="1:3">8</div>
</div>  

Ответ №4:

Вы можете сделать это намного проще, если используете jQuery .index()

Это так же просто, как сделать это:

 $(".box").click(function(){

  var i = $(this).index();     
  alert(i);

});
  

ДЕМОНСТРАЦИЯ: http://jsbin.com/zoxirafufo/edit?html ,js, консоль, вывод