DEV Community

Daniel Mayovsky
Daniel Mayovsky

Posted on

Multiple functions for single eventListener

So, recently I ran into a challenge of managing my keydown listening functions. One of my components needs a straight connection/hook with the original window.keyDown event.

At first I had something like this:

//... other component stuff
if( firstUpdate === 0 ){
window.addEventListener("keydown", function(event){
    //... function stuff

This code will only bind the function once the module has been updated once (one from render, Mithril.js).

The problem is that as soon as this component appears later, without reloading the page, it will bind the function again, and it will either rewrite, or fire both.

so I found a better solution to this, by putting all the window.keyDown events into one module, and then exporting the array of functions that have to be fired.

// initiating the array
let keyDown = [];
window.addEventListener( "keydown", function(event){
    keyDown.forEach( func => { func(event) } );

export { keyDown };

The function above will just run the functions in the array, and pass the event data into them. At the end of the file, i just export the array to be modified later by my components.

Example Mithril.js component:

import { keyDown } from 'WindowEvents.js'

const Component = {
    oninit(vnode){ = false;
        this.keyDownFunction = function(e){ = ! };
        // add function to the array
        keyDown.push ( this.keyDownFunction )
        // remove function from the array
        keyDown.splice( keyDown.indexOf(this.keyDownFunction), 1);

You can see I can remove the function from the array, to not make it fire twice when I have rendered the component again later.

It's not a good idea to use window events if you have an MVC library, just use their events. But in certain cases you have to access the window, and this was a solution for me.

Discussion (0)