我正在尝试在onclick事件中传递参数。以下是示例代码:
<div id="div"></div>
<script language="javascript" type="text/javascript">
var div = document.getElementById('div');
for (var i = 0; i < 10; i++) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = i + '';
link.onclick= function() { onClickLink(i+'');};
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}
function onClickLink(text) {
alert('Link ' + text + ' clicked');
return false;
}
</script>
但是,每当我点击任何链接时,警报始终会显示“Link 10 clicked”!
谁能告诉我我做错了什么?
由于
答案 0 :(得分:52)
这是因为一旦调用函数,i就会向上传播范围。您可以使用闭包来避免此问题。
for (var i = 0; i < 10; i++) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = i + '';
link.onclick = (function() {
var currentI = i;
return function() {
onClickLink(currentI + '');
}
})();
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}
或者如果您想要更简洁的语法,我建议您使用Nick Craver的解决方案。
答案 1 :(得分:37)
这种情况正在发生,因为它们都引用了相同的 i
变量,它正在改变每个循环,并在循环结束时保留为10
。你可以使用这样的闭包来解决它:
link.onclick = function(j) { return function() { onClickLink(j+''); }; }(i);
或者,将this
设为您在该处理程序中点击的链接,如下所示:
link.onclick = function(j) { return function() { onClickLink.call(this, j); }; }(i);
答案 2 :(得分:3)
link.onclick = function() { onClickLink(i+''); };
是一个闭包并存储对变量i
的引用,而不是创建函数时i
保存的值。一种解决方案是将for
循环的内容包装在一个函数中:
for (var i = 0; i < 10; i++) (function(i) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = i + '';
link.onclick= function() { onClickLink(i+'');};
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}(i));
答案 3 :(得分:1)
试试这个:
<div id="div"></div>
<script language="javascript" type="text/javascript">
var div = document.getElementById('div');
for (var i = 0; i < 10; i++) {
var f = function() {
var link = document.createElement('a');
var j = i; // this j is scoped to our anonymous function
// while i is scoped outside the anonymous function,
// getting incremented by the for loop
link.setAttribute('href', '#');
link.innerHTML = j + '';
link.onclick= function() { onClickLink(j+'');};
div.appendChild(link);
div.appendChild(document.createElement('br')); // lower case BR, please!
}(); // call the function immediately
}
function onClickLink(text) {
alert('Link ' + text + ' clicked');
return false;
}
</script>
答案 4 :(得分:1)
或者你可以使用这一行:
link.setAttribute('onClick', 'onClickLink('+i+')');
而不是这一个:
link.onclick= function() { onClickLink(i+'');};
答案 5 :(得分:1)
另一种简单的方式(可能不是最好的做法),但有点像魅力。使用javascript动态构建元素的HTML标记(hyperLink或Button),也可以传递多个参数。
// variable to hold the HTML Tags
var ProductButtonsHTML ="";
//Run your loop
for (var i = 0; i < ProductsJson.length; i++){
// Build the <input> Tag with the required parameters for Onclick call. Use double quotes.
ProductButtonsHTML += " <input type='button' value='" + ProductsJson[i].DisplayName + "'
onclick = \"BuildCartById('" + ProductsJson[i].SKU+ "'," + ProductsJson[i].Id + ")\"></input> ";
}
// Add the Tags to the Div's innerHTML.
document.getElementById("divProductsMenuStrip").innerHTML = ProductButtonsHTML;
答案 6 :(得分:1)
最好创建一个专用函数来创建链接,这样就可以避免创建两个匿名函数。因此:
<div id="div"></div>
<script>
function getLink(id)
{
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = id;
link.onclick = function()
{
onClickLink(id);
};
link.style.display = 'block';
return link;
}
var div = document.getElementById('div');
for (var i = 0; i < 10; i += 1)
{
div.appendChild(getLink(i.toString()));
}
</script>
虽然在这两种情况下你最终都有两个函数,但我认为最好将它包装在一个语义上更容易理解的函数中。
答案 7 :(得分:1)
onclick vs addEventListener。也许是一个偏好的问题(IE> 9)。
// Using closures
function onClickLink(e, index) {
alert(index);
return false;
}
var div = document.getElementById('div');
for (var i = 0; i < 10; i++) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.innerHTML = i + '';
link.addEventListener('click', (function(e) {
var index = i;
return function(e) {
return onClickLink(e, index);
}
})(), false);
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}
如何使用普通的data- *属性,而不是像封闭一样酷,但是......
function onClickLink(e) {
alert(e.target.getAttribute('data-index'));
return false;
}
var div = document.getElementById('div');
for (var i = 0; i < 10; i++) {
var link = document.createElement('a');
link.setAttribute('href', '#');
link.setAttribute('data-index', i);
link.innerHTML = i + ' Hello';
link.addEventListener('click', onClickLink, false);
div.appendChild(link);
div.appendChild(document.createElement('BR'));
}
答案 8 :(得分:0)
这将在不与HTML耦合的情况下从JS运行:
document.getElementById("click-button").onclick = onClickFunction;
function onClickFunction()
{
return functionWithArguments('You clicked the button!');
}
function functionWithArguments(text) {
document.getElementById("some-div").innerText = text;
}