javascript addEventListener将调用方作为参数传递

u4dcyp6a  于 2023-01-04  发布在  Java
关注(0)|答案(1)|浏览(158)

我有下面的代码。我的问题是,当单击时,事件被触发,但传递的参数不正确。它传递的是最后一个动态创建的行,即dataStructure.length值。有人知道如何解决这个问题吗?

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); 
}
wnavrhmk

wnavrhmk1#

function(){handleRowClick(i);}中的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 backup来支持IE〈= 8,它不能正确地获得this,因此您仍然需要查看closures/bind来获得您想要的对象。)
还有:

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

缺少vari是一个意外全局变量。

row.setAttribute('id', i);

避免在HTML文档中使用getAttribute/setAttribute。它们在IE中不起作用。请使用DOM Level 2 HTML属性,它们更可靠,可读性更强:row.id= i.

相关问题