问题在循环中分配事件监听器 - javascript

时间:2014-06-02 19:20:46

标签: javascript google-chrome-extension

我制作了自定义Chrome扩展程序 - 书签管理器。它工作正常,但是我在删除链接方面遇到了问题:如果给出了3个链接,并且在第二个链接上单击了删除按钮,则将删除2和3。

html + js here:http://jsfiddle.net/6Txr9/

由于这是一个扩展,内联javascript不可用,必须使用事件监听器完成。

计数器和linkContainer在本地保存。这允许数据在ext启动之间保持不变,并确保所有@id都是唯一的。我们的想法是indexDeleters()每次调用时都会为每个按钮添加一个唯一的eventlistener,这将导致它只删除该行。

任何输入都表示赞赏!

请求的代码(与上面的链接相同):

JS

function addCats() 
{
    var linkCounter = localStorage['counter']
    var catsList = document.getElementById('catsList');
    var linkName = document.getElementById('linkName');
    var a = document.createElement('a');
    var linkContainer = document.getElementById('linkContainer');
    a.appendChild(document.createTextNode(document.getElementById('linkName').value));
    a.setAttribute('href', 'http://google.com/');
    a.setAttribute('target', '_blank');
    var deleteLink = document.createElement('img');
    deleteLink.setAttribute('src', 'red_x.png');
    deleteLink.setAttribute('align', 'right');
    deleteLink.setAttribute('id', linkCounter);
    var tr = document.createElement('tr');
    var linkCell = document.createElement('td');
    var xCell = document.createElement('td');
    linkCell.appendChild(a);
    xCell.appendChild(deleteLink);
    xCell.setAttribute('align', 'right');
    tr.appendChild(linkCell);
    tr.appendChild(xCell);
    linkContainer.appendChild(tr);
    catsList.value = '';
    linkName.value = '';
    localStorage['container'] = JSON.stringify(linkContainer.innerHTML);
    indexDeleters();
    linkCounter ++;
    localStorage['counter'] = linkCounter;
}

document.getElementById('addToList').onclick = addCats;
function indexDeleters()
{
    var Xs = document.getElementsByTagName('img');
    var arr = []
    for (var i=0; i<Xs.length; i++)
    {
        arr.push(Xs[i]);
    }
    for (var i=0; i<arr.length; i++)
    {
        var Id = arr[i].getAttribute('id');
        arr[i].addEventListener('click', function(){removeRow(Id);}, false);
    }
}

function removeRow(Id)
{
    console.log('Call to remove id at ' + Id)
    var Table = document.getElementById('linkContainer');
    var Tr = document.getElementById(Id).parentNode.parentNode
    Tr.parentNode.removeChild(Tr);
    localStorage['container'] = JSON.stringify(document.getElementById('linkContainer').innerHTML);
}

window.onload = function() 
{
    if (localStorage.getItem('counter') == null)
    {
        localStorage['counter'] = 0
    }
    document.getElementById('linkContainer').innerHTML = JSON.parse(localStorage['container']);
    indexDeleters();
}

HTML

<body>
<h2 align="center">Bookmark Manager</h2>
<table>
    <tr>
        <td colspan="5">
            <table id="linkContainer" width="100%"></table>
        </td>
    </tr>
    <tr>
        <td nowrap>Display Name:</td>
        <td>
            <input type="text" id="linkName"/>
        </td>
        <td nowrap>Cat IDs:</td>
        <td>
            <input type="text" id="catsList"/>
        </td>
        <td>
            <button type="button" id="addToList">Add</button>
        </td>
    </tr>
</table>
<script src="popup.js"></script>
</body>

1 个答案:

答案 0 :(得分:1)

有关问题的解释,请参阅JavaScript closure inside loops – simple practical example

在您的情况下,您可以直接访问事件处理程序中的DOM元素,这样它就不依赖于任何循环变量。

arr[i].addEventListener('click', function(){removeRow(this.id);}, false);