简体   繁体   English

在 Javascript onClick 事件中传递参数

[英]Passing parameters in Javascript onClick event

I'm trying to pass a parameter in the onclick event.我试图在 onclick 事件中传递一个参数。 Below is a sample code:下面是一个示例代码:

<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谢谢

This happens because the i propagates up the scope once the function is invoked.发生这种情况是因为一旦调用函数, i 就会向上传播范围。 You can avoid this issue using a closure.您可以使用闭包来避免此问题。

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 的解决方案。

This is happening because they're all referencing the same i variable, which is changing every loop, and left as 10 at the end of the loop.发生这种情况是因为它们都引用了相同的i变量,该变量在每个循环中都发生了变化,并在循环结束时保留为10 You can resolve it using a closure like this:您可以使用这样的闭包来解决它:

link.onclick = function(j) { return function() { onClickLink(j+''); }; }(i);

You can give it a try here你可以在这里试一试

Or, make this be the link you clicked in that handler, like this:或者,将this设为您在该处理程序中单击的链接,如下所示:

link.onclick = function(j) { return function() { onClickLink.call(this, j); }; }(i);

You can try that version here您可以在此处尝试该版本

link.onclick = function() { onClickLink(i+''); };

Is a closure and stores a reference to the variable i , not the value that i holds when the function is created.是一个闭包并存储对变量i的引用,而不是创建函数时i持有的值。 One solution would be to wrap the contents of the for loop in a function do this:一种解决方案是将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));

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;

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.虽然在这两种情况下你最终都会得到两个函数,但我认为最好将它包装在一个在语义上更容易理解的函数中。

onclick vs addEventListener. onclick 与 addEventListener。 A matter of preference perhaps (where IE>9).也许是偏好问题(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'));
}

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>

or you could use this line:或者你可以使用这一行:

 link.setAttribute('onClick', 'onClickLink('+i+')');

instead of this one:而不是这个:

link.onclick=  function() { onClickLink(i+'');};

This will work from JS without coupling to HTML:这将适用于 JS 而不耦合到 HTML:

document.getElementById("click-button").onclick = onClickFunction;

function onClickFunction()
{
    return functionWithArguments('You clicked the button!');
}

function functionWithArguments(text) {
    document.getElementById("some-div").innerText = text;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM