使用参数承载功能添加和删除事件侦听器

And*_*aur 6 javascript

好的,第一次在这里发布。我几天来一直在寻找有关此问题的帖子,但找不到解决方法。

我有一个具有唯一ID的图像矩阵(基本排列的球体)。我想为上述领域添加不同的功能。因此,我继续添加事件侦听器。到目前为止一切都很好。触发第一个事件后,我希望所有领域都更改其事件侦听器,因此我继续删除所有事件侦听器并添加新的事件侦听器。我无法删除事件监听器。

添加事件:

for (let i = 0; i < 11; i++) {
    for (let j = 0; j < 11; j++) {
        if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
            let ball = document.getElementById(i.toString() + j.toString());
            ball.addEventListener('click', removeBall(i, j));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

removeBall():

var removeBall = function(i, j) {
    return function curried_func(ii, jj) {
        let ball = document.getElementById(i.toString() + j.toString());
        ball.src = "./public/assets/ball_empty.png";
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用的是curried函数方法,因为它是我尝试过的最后一种方法,除了从e(事件)参数中检索对象数据外,由于未定义e,该方法似乎不起作用。或使用处理程序。或使用绑定。

移除事件:

for (let i = 0; i < 11; i++) {
    for (let j = 0; j < 11; j++) {
        if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
            let ball = document.getElementById(i.toString() + j.toString());
            // ball.somethingToRevmoveEvent?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我确实有必要提到这也是我的第一个javascript严肃项目,因此,如果有人有更好的解决方案或解决方法(而不是为功能添加和删除事件100次),请共享。

供参考矩阵 -用户应删除1个球,此时该点变成黑色,然后任何球都可以跳过另一个球以填充空白点(“跳过球”被删除)。我认为这是某种中国跳棋难题。

Ale*_*ied 3

虽然柯里化很好,但这意味着每次调用它时都会返回一个新函数,而不是同一函数的副本。您需要以某种方式保存对正在绑定的函数的引用,然后在删除事件侦听器时使用它。如果没有其余代码的上下文,我将尝试在下面对其进行伪编码:

const eventMap = new Map();

function getMapKey(i, j) {
    return `${i},${j}`;
}

function addEvents() {
    for (let i = 0; i < 11; i++) {
        for (let j = 0; j < 11; j++) {
            if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
                let ball = document.getElementById(i.toString() + j.toString());
                let removeBallFn = removeBall(i, j);
                let key = getMapKey(i, j);
                eventMap.set(key) = removeBallFn;
                ball.addEventListener('click', removeBallFn);
            }
        }
    }
}

function removeEvents() {
    for (let i = 0; i < 11; i++) {
        for (let j = 0; j < 11; j++) {
            if ((i > 1 && i < 9 && j > 1 && j < 9) && checkCorners(i, j) === true) {
                let ball = document.getElementById(i.toString() + j.toString());
                let key = getMapKey(i, j);
                let removeBallFn = eventMap.get(key) = removeBallFn;
                ball.removeEventListener('click', removeBallFn);
                eventMap.delete(key);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是未经测试的,因为我没有你的其余代码。原理是,每次生成“删除”函数时,我们都会使用基于循环中该点的和值串联的唯一键将其存储在Map(此处) 中。然后,当我们需要删除时,使用相同的键将相同的“删除”函数从地图中拉出,并将其传递给. 还有其他方法可以做到这一点——这只是一种选择。考虑到代码的更大上下文,根据需要进行调整。希望这对您有用!eventMapijremoveEventListener