我正在制作一个会生成大量按钮的用户脚本,而且我似乎无法为它们提供所有独特的功能。
我已经尝试过了
downArrow.onclick = function (){downVote(id, username)};<br>
和
downArrow.onclick = "downVote(\"" + id + "\", \"" + username + "\")";
但他们不起作用。然后我在某处读到只有以下工作:
downArrow.addEventListener('click', downVote(id, username), false);
这会导致所有按钮仅下调迭代的最后一个ID和用户名。
我希望他们都拥有独特的onclick功能。
整个循环:
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){}
}
答案 0 :(得分:4)
bind是针对这种情况而发明的:
upArrow.addEventListener('click', upVote.bind(upArrow, id, username), false);
应该做的。
答案 1 :(得分:3)
由于JavaScript没有块范围(将附带ES6),请尝试以下操作:
downArrow.addEventListener('click', function(uid, uname) {
return function() {
downVote(uid, uname);
};
}(id, username), false);
当调用匿名函数(立即发生)时,您捕获当前状态id
和username
并在调用内部函数时使用它(当用户单击按钮时发生)。
在ES6中,您可以使用let id = ...
来定义具有块范围的变量,并且您发布的代码应该可以正常工作。
答案 2 :(得分: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]));
}