Dom Element onclick (MooTools :: опционально) - PullRequest
0 голосов
/ 17 июня 2010

Рассмотрим следующий пример:

function async_callback(array1, array2, array3) {
  // All arrays are equal length

  for(var i = 0; i < array1.length; i++) {
    var myElement = new Element('div', { 'id': 'dvMy' + i, 'events': { 'click': function() { SomeFunction(array1[i], array2[i], array3[i] } }});
    $(document).appendChild(myElement);
  }
}

Теперь, когда я щелкаю свой элемент, я получаю нулевое значение для всех трех аргументов. Я даже попытался сделать: myElement.onclick = SomeFunction; // но это не допустит аргументов Я знаю, что могу создать строку и использовать eval (), и это работает, но мне не нравится eval ().

Есть идеи ???

Кстати: это простой пример для репликации проблемы, а не фактический код.

Ответы [ 2 ]

2 голосов
/ 17 июня 2010

Это ваш обработчик:

function() { SomeFunction(array1[i], array2[i], array3[i] } }

Ко времени выполнения цикл завершится и, следовательно, i будет равен length массива в соответствии с условным оператором (i < array1.length) и оператором итерации (i++) .

Самый простой способ решить эту проблему - обернуть обработчик в дополнительную немедленно выполняемую функцию и передать ей i, что приведет к сохранению значения i в новом замыкании:

for(var i = 0; i < array1.length; i++) {
    var myElement = new Element('div', { 'id': 'dvMy' + i, 'events': {
        'click': (function(i){
            return function() { SomeFunction(array1[i], array2[i], array3[i] } };
         }(i))
    });
    $(document).appendChild(myElement);
}
1 голос
/ 17 июня 2010

Это классика: при запуске обработчика click для i устанавливается последнее значение, которое он достиг в цикле, который в данном случае равен array1.length.Чтобы получить то, что вы хотите, вам нужно вызвать функцию для создания обработчика кликов и передать ему значение i:

function async_callback(array1, array2, array3) {
  function createClickHandler(n) {
    return function() {
      SomeFunction(array1[n], array2[n], array3[n]);
    };
  }

  // All arrays are equal length
  for(var i = 0; i < array1.length; i++) {
    var myElement = new Element('div', {
      'id': 'dvMy' + i,
      'events': {
        'click': createClickHandler(i)
      }
    });
    $(document).appendChild(myElement);
  }
}
...