在 Javascript onClick 事件中传递参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3495679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing parameters in Javascript onClick event
提问by fatcatz
I'm trying to pass a parameter in the onclick event. Below is a sample code:
我试图在 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>
However whenever I click on any of the links the alert always shows 'Link 10 clicked'!
然而,每当我点击任何链接时,警报总是显示“点击链接 10”!
Can anyone tell me what I'm doing wrong?
谁能告诉我我做错了什么?
Thanks
谢谢
回答by Jamie Wong
This happens because the i propagates up the scope once the function is invoked. You can avoid this issue using a closure.
发生这种情况是因为一旦调用函数, 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'));
}
Or if you want more concise syntax, I suggest you use Nick Craver's solution.
或者,如果您想要更简洁的语法,我建议您使用 Nick Craver 的解决方案。
回答by Nick Craver
This is happening because they're all referencing the sameivariable, which is changing every loop, and left as 10at the end of the loop. You can resolve it using a closure like this:
发生这种情况是因为它们都引用了相同的i变量,该变量在每个循环中都发生了变化,并10在循环结束时保持不变。您可以使用这样的闭包来解决它:
link.onclick = function(j) { return function() { onClickLink(j+''); }; }(i);
Or, make thisbe the link you clicked in that handler, like this:
或者,成为this您在该处理程序中单击的链接,如下所示:
link.onclick = function(j) { return function() { onClickLink.call(this, j); }; }(i);
回答by Ryan Tenney
link.onclick = function() { onClickLink(i+''); };
Is a closure and stores a reference to the variable i, not the value that iholds when the function is created. One solution would be to wrap the contents of the forloop in a function do this:
是一个闭包并存储对变量的引用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));
回答by Richard JP Le Guen
Try this:
尝试这个:
<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>
回答by aniri
or you could use this line:
或者你可以使用这一行:
link.setAttribute('onClick', 'onClickLink('+i+')');
instead of this one:
而不是这个:
link.onclick= function() { onClickLink(i+'');};
回答by Kiran Kumar Veerabatheni
Another simple way ( might not be the best practice) but works like charm. Build the HTML tag of your element(hyperLink or Button) dynamically with javascript, and can pass multiple parameters as well.
另一种简单的方法(可能不是最佳实践)但效果很好。使用 javascript 动态构建元素(超链接或按钮)的 HTML 标记,并且还可以传递多个参数。
// 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;
回答by Yeti
It is probably better to create a dedicated function to create the link so you can avoid creating two anonymous functions. Thus:
最好创建一个专用函数来创建链接,这样您就可以避免创建两个匿名函数。因此:
<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>
Although in both cases you end up with two functions, I just think it is better to wrap it in a function that is semantically easier to comprehend.
虽然在这两种情况下你最终都会得到两个函数,但我认为最好将它包装在一个语义上更容易理解的函数中。
回答by Alex Nolasco
onclick vs addEventListener. A matter of preference perhaps (where IE>9).
onclick 与 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'));
}
How abut just using a plain data-* attribute, not as cool as a closure, but..
仅仅使用一个普通的 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'));
}

