【问题标题】:Passing value of a variable to event function将变量的值传递给事件函数
【发布时间】:2021-07-11 00:21:12
【问题描述】:

我有一些 javascript 创建一些带有点击事件的按钮到传递该按钮标识符的函数。标识符是创建它们的代码中的一个变量。但是,变量是通过引用传递的,因此函数获取的值是变量的最后设置值,而不是创建按钮时的值。

这似乎是一个非常简单且常见的飞行员错误,但我无法在此处或更广泛的网络上找到任何答案。

在下面的示例中,我希望 Buttonclicked 函数中的 ClickedID 是创建按钮时 CreateButtons 函数中 ButtonID 的值(并显示在按钮的标题中),而不是函数时的 ButtonID完成。

function CreateButtons() {
  var Buttons = document.getElementById("Buttons");
  var Button = null;
  var ButtonID = 0;

  for (ButtonID = 0; ButtonID < 6; ButtonID++) {
    Button = document.createElement("button");
    Button.appendChild(document.createTextNode("Button " + ButtonID));
    Button.onclick = function() {ButtonClicked(ButtonID);};
    Buttons.appendChild(Button); }
}

function ButtonClicked (ClickedID) {
  alert("You clicked button " + ClickedID);
}
button {
  display: block;
  width: 150px;
  margin-bottom: 10px;
<button onclick="CreateButtons();">Create Buttons</button>
<div id="Buttons"></div>

【问题讨论】:

    标签: javascript variables events arguments


    【解决方案1】:

    您可以使用IIFE(Immediately-invoked Function Expression)轻松实现此目的

    您将获得循环结束的buttonID,即6。您可以做的是创建一个IIFE,这样每次迭代都会创建一个新的scope 和一个新的ButtonID

    function CreateButtons() {
      var Buttons = document.getElementById("Buttons");
      var Button = null;
      let ButtonID = 0;
    
      for (ButtonID = 0; ButtonID < 6; ButtonID++) {
        (function(btnId) {                // change
          Button = document.createElement("button");
          Button.appendChild(document.createTextNode("Button " + btnId));
          Button.onclick = function() {
            ButtonClicked(btnId);
          };
          Buttons.appendChild(Button);
        })(ButtonID);                    // change
      }
    }
    
    function ButtonClicked(ClickedID) {
      alert("You clicked button " + ClickedID);
    }
    button {
      display: block;
      width: 150px;
      margin-bottom: 10px;
    }
    <button onclick="CreateButtons();">Create Buttons</button>
    <div id="Buttons"></div>

    来自 ES6 ## - 使用 let。 let 和 const 声明了一个阻塞作用域的局部变量

    只需创建一个新的局部范围变量,如下所示

    for (let ButtonID = 0; ButtonID < 6; ButtonID++) {
    

    function CreateButtons() {
      var Buttons = document.getElementById("Buttons");
      var Button = null;
    
      for (let ButtonID = 0; ButtonID < 6; ButtonID++) {
        Button = document.createElement("button");
        Button.appendChild(document.createTextNode("Button " + ButtonID));
        Button.onclick = function() {
          ButtonClicked(ButtonID);
        };
        Buttons.appendChild(Button);
      }
    }
    
    function ButtonClicked(ClickedID) {
      alert("You clicked button " + ClickedID);
    }
    button {
      display: block;
      width: 150px;
      margin-bottom: 10px;
    }
    <button onclick="CreateButtons();">Create Buttons</button>
    <div id="Buttons"></div>

    【讨论】:

    • 非常感谢您的回答,工作正常。
    【解决方案2】:

    您可以使用let 代替var 来解决此问题:

    for (let ButtonID = 0; ButtonID < 6; ButtonID++)
    

    而不是

    var ButtonID = 0;
    

    您可以找到文档here

    let 创建块范围变量(因此附加到for 循环),而var 创建一个函数范围变量(附加到CreateButton 函数)。

    var 的情况下,当onclick 被调用时,ButtonID 为 6,因为循环已完成。在let 的情况下,循环内ButtonID 的每个值都会被保留,onclick 处理函数可以访问。

    这个用例详细解释here。它包含两种解决方案 - 使用 let 和 IIFE(由 decpk 发布)

    function CreateButtons() {
      var Buttons = document.getElementById("Buttons");
      var Button = null;
    
      for (let ButtonID = 0; ButtonID < 6; ButtonID++) {
        Button = document.createElement("button");
        Button.appendChild(document.createTextNode("Button " + ButtonID));
        Button.onclick = function() {ButtonClicked(ButtonID);};
        Buttons.appendChild(Button); }
    }
    
    function ButtonClicked (ClickedID) {
      alert("You clicked button " + ClickedID);
    }
    button {
      display: block;
      width: 150px;
      margin-bottom: 10px;
    <button onclick="CreateButtons();">Create Buttons</button>
    <div id="Buttons"></div>

    【讨论】:

    • 非常感谢您的回答,工作正常。
    猜你喜欢
    • 2014-01-28
    • 2016-05-08
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    相关资源
    最近更新 更多