如何以编程方式添加 JavaScript 中索引依赖的事件侦听器?

问题描述 投票:0回答:1

我正在尝试使用以下代码以编程方式向 Photoshop 插件添加一个偶数侦听器:

actionObject = [];
actionObject[0] =  {name: "A1", id: "95ce"};
actionObject[1] =  {name: "B2", id: "9dk2"};
.
.
actionObject[10] =  {name: "H6", id: "9334"};


for (i = 0; i < actionObject.length; i++ ){
    console.log("#btn" + actionObject[i].name);
    var action = actionObject[i];
    $("#btn" + action.name).click(async function () {
        await ExecuteAsModal(() => runAction(action));
    });
}

我面临的问题是,当触发此事件时,无论我按下哪个按钮,它总是尝试使用 actionObject 数组中的最后一个“action”运行“runAction”。 在这种情况下,它总是尝试使用

运行它
action={name: "H6", id: "9334"}

如何确保每个按钮都以正确的“操作”运行“actionObject”?

javascript event-handling
1个回答
0
投票

您遇到的问题是一个经典的闭包问题。在循环中,当您使用

$("#btn" + action.name).click(...)
定义单击事件处理程序时,
action
变量是通过引用捕获的,而不是通过值捕获的。因此,当单击事件发生时,循环已经完成,并且
action
保存循环中分配给它的最后一个值。

为了解决这个问题,您需要为循环的每次迭代创建一个新的作用域,以便每个事件处理程序捕获

action
的正确值。 例如,您可以使用 IIFE 来完成此操作,如下所示:

for (var i = 0; i < actionObject.length; i++) {
    (function(action) {
        $("#btn" + action.name).click(async function () {
            await ExecuteAsModal(() => runAction(action));
        });
    })(actionObject[i]);
}

可能更好的方法是使用箭头函数,所以它看起来像这样:

for (let i = 0; i < actionObject.length; i++) {
    let action = actionObject[i];
    $(`#btn${action.name}`).click(async () => { 
        await ExecuteAsModal(() => runAction(action));
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.