2010-04-18 4 views
2

У меня есть следующий код. И моя проблема заключается в том, что при нажатии, событие запускается, но переданный аргумент неверен. Он передает последнюю динамически создаваемую строку, то есть значение dataStructure.length. Кто-нибудь знает, как обойти это?addEventListener pass caller как аргумент

 var table = document.getElementById('output');     

     for(i =0; i<dataStructure.length; i++){ 
      var row = document.createElement('tr'); 
      row.setAttribute('id', i); 
      var url = dataStructure[i].url; 

      if(document.addEventListener) 
       row.addEventListener('click', function(){handleRowClick(i);}, false); 
      var obj = dataStructure[i]; 
      var cellCount = 0; 
      for(field in obj){ 
       var cell = document.createElement('td'); 
       cell.setAttribute('id', cellCount++); 
       //cell.addEventListener('click', function(){window.open(dataStructureObj.links[i].url);}, false); 
       cell.innerHTML = obj[field]; 
       row.appendChild(cell); 
      } 
      cellCount = 0; 
      table.appendChild(row); 
     }   
     } 

     function handleRowClick(rowClicked){ 
      var rowHTML = rowClicked.innerHTML; 
      var cells = rowHTML.getElementsByTagName('td'); 
      for(cell in cells) 
      { 
       alert(cell.value); 
      } 
      window.open(cells[1].innerHTML); 
     } 

ответ

2

i в function(){handleRowClick(i);} является переменной i петли. Когда функция вызывается, цикл является завершенным, а i содержит последнее значение, которое он сделал в конце цикла, не значение, которое оно удерживало при создании function(){}.

Это проблема замкнутого контура. См this question для решений с использованием либо затворов или Function#bind:

row.addEventListener('click', handleRowClick.bind(window, i), false); 

Однако, вы на самом деле не использовать это i в данный момент. Было бы проще сказать:

row.addEventListener('click', handleRowClick, false); 

, а затем использовать this, чтобы получить строку:

function handleRowClick(){ 
    window.open(this.cells[1].innerHTML); 
} 

(Side Примечание: к сожалению, если вы добавите attachEvent резервного копирования для поддержки IE < = 8, то не получает this права, так что вы все еще смотреть на закрытий/связать, чтобы получить объект, который вы хотите)

. также:

for(i =0; i<dataStructure.length; i++){ 

Отсутствует var: i является случайным глобальным.

 row.setAttribute('id', i); 

Избегайте getAttribute/setAttribute в HTML-документах. Они не делают то, что должны в IE. Вместо этого используйте свойства HTML DOM уровня 2, они более надежны и читаемы: row.id= i.

+0

Это сделало трюк :) Никогда не делал этого раньше – Ryan

Смежные вопросы