使用 JSON 关联数组为多个元素添加事件监听器
Using JSON Associative Array to Add Event Listeners to Multiple Elements
我正在使用 JavaScript 遍历 JSON 关联数组,以将事件侦听器添加到同一页面上的不同表单集合。数组的键是页面上对象的ID,值是提交表单时出现在确认框中的消息。
例如,我有一系列带有 ID 的表单:confirm_1
、confirm_2
、confirm 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
。这个问题可以用不同的方式解决。下面我说一下三种解决方法。
- 如果你可以使用 ES6,你可以只使用
let
而不是 var
来声明 key
变量。由于 let
具有块作用域,每个循环块将有自己的 space 用于 key
变量。
- 通过将值绑定到回调函数。
- 通过使用立即调用功能。
我已在下面的示例中解决了所有这些问题,并对其进行了评论以提高可读性。
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>
我正在使用 JavaScript 遍历 JSON 关联数组,以将事件侦听器添加到同一页面上的不同表单集合。数组的键是页面上对象的ID,值是提交表单时出现在确认框中的消息。
例如,我有一系列带有 ID 的表单:confirm_1
、confirm_2
、confirm 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
。这个问题可以用不同的方式解决。下面我说一下三种解决方法。
- 如果你可以使用 ES6,你可以只使用
let
而不是var
来声明key
变量。由于let
具有块作用域,每个循环块将有自己的 space 用于key
变量。 - 通过将值绑定到回调函数。
- 通过使用立即调用功能。
我已在下面的示例中解决了所有这些问题,并对其进行了评论以提高可读性。
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>