Skip to content
Advertisement

JS remove event listener with no condition?

I have the following code

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

As you can see the resize event listener recursively calls setSize(). I did this so that I could handle initial size setup and window resizing in the same function.

The problem is that every recurse will add an additional eventListener, rather than replacing the last. So I need to remove the resize event listener on each recurse to avoid them stacking and eventually having dozens of event listeners triggering on window resize.

The documentation says that the removeEventListener() must take an event parameter that defines the condition upon which it will trigger. I don’t want this, as I want it to trigger the moment the code is read at the beginning of the function. Like so

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

Is there a way to do this, or some alternative method that you recommend?

Edit: The motivation behind my question is that I’d like an elegant single function solution that handles both initial setup and later window resizes, rather than having to define setSize(), call it, then create an event listener that also calls it.

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.

I quickly realized after I posted this question that the reason why I must specify the event on removeEventListener() is because that’s the specific event that setSize() is bound to trigger on. I thought that it was saying it would remove the event listener only when the event triggers, rather than immediately removing the event listener which is what I want.

Advertisement

Answer

You can do what you want, but it doesn’t provide you to remove the listener in the handler. A short example would be like this:

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

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

This way you can call setSize for initialization while attaching the event. The function returns itself so that there will be a reference for addEventListener after calling setSize. Later when the event fires, the return value is ignored, because the handler will be called from the event queue.

Or, you can use an IIFE to initialize the canvas.

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

document.addEventListener('resize', setSize);

But, at the end of the day, you shouldn’t make such tricks, like Kaiido has said in the comments, “An elegant code is a code that is obvious“. Just call the function for initialization. Dropping the useless return statement from the resize handler will save you a microsecond or two for the canvas updating.

Advertisement