6

我正在开发一个可以制作很多按钮的用户脚本,但我似乎无法为它们提供一个独特的功能。

我已经试过了

 downArrow.onclick = function (){downVote(id, username)};<br>

 downArrow.onclick = "downVote(\"" + id + "\", \"" + username + "\")";

但它们不起作用。然后我在某处读到只有以下内容:

 downArrow.addEventListener('click', downVote(id, username), false);

这导致所有按钮只会对迭代的最后一个 ID 和用户名投反对票。

我希望它们都具有独特的 onclick 功能。

整个for循环:

var targetPosts = document.getElementsByClassName("thing message");
for (var i=0;i<targetPosts.length;i++) 
    {
    try
      {
        id = targetPosts[i].getAttribute("data-fullname");
        username = targetPosts[i].childNodes[4].childNodes[1].childNodes[0].childNodes[1].childNodes[1].childNodes[0].innerHTML;

        var upArrow=document.createElement("DIV");
        upArrow.className = "arrowUp";
        upArrow.id = id + "up";
        upArrow.addEventListener('click', function(){ upVote(id, username)} , false);

        var downArrow=document.createElement("DIV");
        downArrow.className = "arrowDown";
        downArrow.id = id + "down";
        downArrow.addEventListener('click', function(){ downVote(id, username)} , false

      targetPosts[i].childNodes[3].appendChild(upArrow);
      targetPosts[i].childNodes[3].appendChild(downArrow);
      }
    catch(err){}
    }
4

3 回答 3

4

bind 就是为这种情况而发明的:

 upArrow.addEventListener('click', upVote.bind(upArrow, id, username), false);

应该做的工作。

于 2013-05-31T13:45:51.767 回答
3

由于 JavaScript 没有块作用域(将随 ES6 提供),请尝试以下操作:

downArrow.addEventListener('click', function(uid, uname) {
    return function() {
        downVote(uid, uname);
    };
}(id, username), false);

调用匿名函数时(立即发生),您捕获当前状态idusername在调用内部函数时使用它(当用户单击按钮时发生)。

在 ES6 中,您可以使用let id = ...块范围定义变量,并且您发布的代码应该可以正常工作。

于 2013-05-31T13:38:08.880 回答
3

我不确定您是如何尝试这样做的(最好显示循环代码),但通常在循环内创建函数不是很安全,因为您可能会错误地引用在循环内更改的变量所以最后,您将使用相同的 id 获得所有功能。解决方案是使用一些辅助功能:

var bindClick = function (element, id, username) {
        element.addEventListener('click', function () {
            downVote(id, username);
        }, false);
    },
    i, mybutton;
for (i = 0 ; i < amountOfUsers ; ++i) {
    mybutton = document.getElementById('downvote-handle-' + i);
    bindClick(mybutton, i, usernames[i]);
}

这种方式i值被复制(按值传递)并且是安全的。

它也可以使用匿名函数来完成,结果将是相同的(但恕我直言,可读性较差):

for (i = 0 ; i < amountOfUsers ; ++i) {
    mybutton = document.getElementById('downvote-handle-' + i);
    (function (element, id, username) {
        element.addEventListener('click', function () {
            downVote(id, username);
        }, false);
    }(mybutton, i, userames[i])); 
}
于 2013-05-31T13:38:51.160 回答