Почему этот html / javascript combo выводит так, как он это делает? - PullRequest
0 голосов
/ 29 июля 2011
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Ovi Maps API Example</title>

  </head>
  <body>
      <button id="butt1" name="butt" type="button">Click Me!</button>
      <button id="butt2" name="butt" type="button">Click Me!</button>
      <button id="butt3" name="butt" type="button">Click Me!</button>
  </body>
   <script src="jquery.js" type="text/javascript" charset="utf-8"></script>
   <script src="foo.js" type="text/javascript" charset="utf-8"></script>
</html>

и ...

$(document).ready(function() {
//alert("ready");
var myClickFunctions = new Array();

//add event handlers to all three buttons
for(var i=1;i<=3;i++){

  myClickFunctions[i]=function(){
    var index = i;
    alert(index);
  }

  var buttonID = "#butt";
  var button  = $(buttonID + i);    
  button.click(myClickFunctions[i]);
}

});

Каждая кнопка печатает 4. Почему это так и как можно заставить каждую из них напечатать значение i, в котором был создан обработчик?

Ответы [ 4 ]

4 голосов
/ 29 июля 2011

Читайте о закрытиях JavaScript и о том, как они работают.Дело в том, что i в button.click(myClickFunctions[i]); внизу будет 4 в конце.Помните, что var index = i не устанавливается при объявлении функции, только при ее вызове.Что вам нужно сделать, это обернуть функцию в замыкание следующим образом:

  myClickFunctions[i]=(function(i){
    return function(){
      var index = i;
      alert(index);
    }
  })(i)

или еще лучше, сделайте это:

//put this anywhere
function myClickFunctions(i){
  return function(){
    alert(i);
  }
}

//and at the end:
button.click(myClickFunctions(i));

Функция myClickFunctions примет текущее значение iи вернуть функцию с уже установленным значением.Это правильный способ сделать это.

2 голосов
/ 29 июля 2011

Ваша анонимная функция, которую вы устанавливаете на myClickFunctions[i], создает замыкание около i.Закрытия закрываются по самой переменной, а не по значению на момент закрытия.Таким образом, к моменту запуска этой функции i равно 4, и поэтому вы всегда получите 4.

Простое решение - вызвать функцию, которая возвращает функцию и фиксирует текущее значение i.

myClickFunctions[i] = (function(curI) {
     return function() {
        var index = curI;
        alert(index);
     };
})(i);

Если это сбивает с толку, тогда я рекомендую прочитать о замыканиях в JavaScript.Через некоторое время они становятся второй натурой.

0 голосов
/ 29 июля 2011

Значение «i», когда цикл заканчивается, равно «4», поэтому каждый раз, когда вы нажимаете на кнопку, число, которое будет показывать вам, равно «4», потому что вы получаете доступ к ссылке «i» иФункция выполняется, когда вы нажимаете кнопку не во время цикла.

Если вы хотите, чтобы число «i» совпадало с идентификатором кнопки, поэтому я предлагаю сделать это.

$(document).ready(function() {
//alert("ready");
var myClickFunctions = new Array();

//add event handlers to all three buttons
for(var i=1;i<=3;i++){

  myClickFunctions[i]=function(){
    var id = $(this).attr('id');
    var index = id.replace('butt', '');
    alert(index);
  }

  var buttonID = "#butt";
  var button  = $(buttonID + i);    
  button.click(myClickFunctions[i]);
}

});
0 голосов
/ 29 июля 2011

Поскольку вы присваиваете новое значение одной и той же переменной каждый раз, когда функция зацикливается, то var Index равен 4 при нажатии любой кнопки.

Быстрый подход к тому, чтобы каждый тег привязки распечатывал свой индекс, заключался бы в следующем:

$('a').click(function() {
    var theAnchors = $('a');
    for (i in theAnchors)
        if (theAnchors[i] == this)
            alert(i);
});

Единственная проблема, с которой я могу столкнуться, заключается в том, что я сомневаюсь, что сравнение равенства объектов будет подтверждено, только если сравниваемые два элемента DOM совпадают, но они могли бы.

Более того, тем не менее, какова конечная цель, которую вы пытаетесь достичь здесь (поскольку я уверен, что создание страницы, которая беспокоит пользователя оповещениями при нажатии на любой якорь, не является вашей намеченной конечной целью).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...