Search code examples
javascriptevent-listener

Javascript Event Listener when nothing is happening after a period of time


I would ask if someone know an Event Listener, that start to work when there aren't pressed button on the Keyboard for a determined period of time, something like that:

document.addEventListener('wait', myFunction);

Solution

  • There isn't a listener that will do that. So perhaps:

    1. Set up a status variable that is reset when a key is pressed.

    2. Create a delay function. In this example I'm returning a promise from the function that can be awaited.

    3. When main is called it awaits the delay promise to be resolved. If no key has been pressed it calls a function and awaits for it to complete, then calls main again, otherwise no further action is taken.

    // Cache the output element used in `writer`
    const output = document.querySelector('.output');
    
    // Initialise the status
    let status = false;
    
    // Check for `keypress` events
    document.addEventListener('keypress', () => status = true);
    
    // Accepts an argument specifying how
    // many milliseconds delay there will be
    function delay(n) {
      return new Promise(res => {
        setTimeout(() => res(), n);
      });
    }
    
    // Random function to test the delay works
    function writer() {
      return new Promise(async res => {
        const str = 'Hello world!';
        for (let i = 0; i <= str.length; i++) {
          await delay(250);
          output.textContent = str.substr(0, i);
        }
        res();
      });
    }
    
    // Wait 3 seconds. If no key has been pressed
    // call the `writer` function. Reset the status, and
    // call `main` again
    async function main() {
    
      await delay(3000);
    
      if (!status) {
        console.log('No key pressed - calling writer()');
        await writer();
      } else {
        console.log('Key pressed - no further action');
      }
    
      status = false;
      main();
    
    }
    
    main();
    <div class="output"></div>