JS 无条件删除事件监听器?

JS remove event listener with no condition?

我有以下代码

function setSize() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    document.addEventListener('resize', setSize)
}

如您所见,resize 事件侦听器递归调用 setSize()。我这样做是为了可以在同一函数中处理初始大小设置和 window 调整大小。

问题是每次递归都会添加一个额外的 eventListener,而不是替换最后一个。所以我需要在每个递归上删除 resize 事件监听器,以避免它们堆叠并最终在 window 调整大小时触发数十个事件监听器。

文档说 removeEventListener() 必须采用 event 参数来定义触发条件。我不想要这个,因为我希望它在函数开头读取代码时触发。像这样

function setSize() {
    document.removeEventListener(setSize) // I want something like this
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    document.addEventListener('resize', setSize)
}

有没有办法做到这一点,或者您推荐一些替代方法?

编辑: 我的问题背后的动机是我想要一个优雅的单一功能解决方案来处理初始设置和以后 window 调整大小,而不是必须定义 setSize(),调用它,然后创建一个事件侦听器也调用它。

function setSize() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}

// I do not want to have to do this:
setSize()
document.addEventListener('resize', setSize)
// I want something more elegant that handles both initial setup and window resize.

我在发布这个问题后很快意识到,我必须在 removeEventListener() 上指定 event 的原因是因为那是 setSize() 必然会触发的特定事件。我以为它是说它只会在事件触发时删除事件监听器,而不是立即删除事件监听器,这正是我想要的。

你可以做你想做的,但它不提供你删除处理程序中的侦听器。一个简短的例子是这样的:

function setSize () {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    return setSize;
}

document.addEventListener('resize', setSize());

这样您就可以在附加事件的同时调用setSize进行初始化。函数 returns 本身,以便在调用 setSize 后会有对 addEventListener 的引用。稍后当事件触发时,return 值将被忽略,因为处理程序将从事件队列中调用。

或者,您可以使用 IIFE 来初始化 canvas。

const setSize = (function setSize () {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    return setSize;
}());

document.addEventListener('resize', setSize);

但是,归根结底,你不应该做这样的把戏,就像 Kaiido 在评论中所说的那样,“优雅的代码是显而易见的代码 ”。只需调用初始化函数即可。从 resize 处理程序中删除无用的 return 语句将为 canvas 更新节省一两微秒。