使用 JSON 关联数组为多个元素添加事件监听器

Using JSON Associative Array to Add Event Listeners to Multiple Elements

我正在使用 JavaScript 遍历 JSON 关联数组,以将事件侦听器添加到同一页面上的不同表单集合。数组的键是页面上对象的ID,值是提交表单时出现在确认框中的消息。

例如,我有一系列带有 ID 的表单:confirm_1confirm_2confirm 2

在同一页上我有这样的东西:

<script type="application/json" id="json_data">{"confirm_1": "Are you sure?", "confirm_2": "Really?", "confirm_3": "Must you?"}</script>
<script src="confirmation.js"></script>

这是confirmation.js:

var data = JSON.parse(document.getElementById('json_data').innerHTML);

for (var key in data) {
   document.getElementById(key).addEventListener('submit', function(event) {
      if (!confirm(data[key])) {
         event.preventDefault();
      }
   });
};

问题是,当我在任何表单上单击提交按钮时,它们都被分配了数组中最后一个元素的确认消息。就像之前所有的 addEventListener 调用都继承了最后一次调用。

我在这里错过了什么?

您遇到问题是因为您已将 key 声明为 var 数据类型。由于它具有功能范围,因此它会使用分配给它的最后一个值进行更新,在您的情况下为 confirm_3 。这个问题可以用不同的方式解决。下面我说一下三种解决方法。

  1. 如果你可以使用 ES6,你可以只使用 let 而不是 var 来声明 key 变量。由于 let 具有块作用域,每个循环块将有自己的 space 用于 key 变量。
  2. 通过将值绑定到回调函数。
  3. 通过使用立即调用功能。

我已在下面的示例中解决了所有这些问题,并对其进行了评论以提高可读性。

var data = {
  confirm_1: "Are you sure?",
  confirm_2: "Really?",
  confirm_3: "Must you?"
};

//Using let
/*for (let key in data) {
  document
    .getElementById(key)
    .addEventListener("click", function (event) {
      alert(data[key]);
    });
}*/


//Using Bind
for (var key in data) {
  document.getElementById(key).addEventListener(
    "click",
    function (message, event) {
      alert(message);
    }.bind(this, data[key])
  );
}

//Using IIF (Immediate Invoking function)

/* for (var key in data) {
  (function(message){
     document
    .getElementById(key)
    .addEventListener("click", function (event) {
      alert(message);
    });
  })(data[key]);
} */
<button id='confirm_1'>confirm_1</button>
<button id='confirm_2'>confirm_2</button>
<button id='confirm_3'>confirm_3</button>