Home > Blockchain >  How to trigger different functions if same key is pressed more than once?
How to trigger different functions if same key is pressed more than once?

Time:04-06

I was a little stuck on figuring out how to trigger different functions if the same key was pressed. For instance, if space was pressed, it would call function1. If space was pressed again, it would call function2. If space was called one more time, it will call function3.

I currently have the following code and it seems like my code never enters the last two if statements. Any tips on how to fix this? Thanks in advance!

document.addEventListener("keydown", function (e) {
    if (e.code == "") {
      function1();
      if (e.code == "") {
        function2();
      
      } 
      if (e.code == "") {
        function3();
      
      } 
    }

CodePudding user response:

JavaScript events are what make sure that they trigger a function when something happens. So, if you want to add several functions you have to make sure something happens to trigger them. So if you say you have to run several functions when a key is pressed it has no meaning if you are not binding some other function to that key. Because if the only thing you have is one key pressing event you cannot possibly think of running multiple functions each time that key is pressed. But you can tweak the code a little bit to run multiple functions too.

Here's an example of how to do that.

HTML:

<p class='p'>Hello<p>

CSS:

.red{
  background:red;
}
.green{
  background:green;
}
.blue{
  background:blue;
}

JS:

let v=0
const p = document.querySelector('.p')
document.body.onkeydown= function (e) {
    if (e.keyCode == 32) {
      switch(v % 3){
        case 0:
          p.classList.add('red')
          p.classList.remove('green')
          p.classList.remove('blue')
          v  = 1
          console.log(v)
          break
        case 1:
          p.classList.add('green')
          p.classList.remove('red')
          p.classList.remove('blue')
          v  = 1
          break
        case 2:
          p.classList.add('blue')
          p.classList.remove('green')
          p.classList.remove('red')
          v  = 1
          break
      }
    }
  }

Here, you can see that I am making sure that another function is running hidden to select the functionality I want.

CodePudding user response:

Since your event handler will be called for every single event, you have to use some sort of debounce function. Basically a timer and some logic that keeps track of how many times the event occured in a given time frame.

Let's start with a little helper function that takes care of delaying the call of your 3 event handler functions.

const debounceKeyPress = (keyCode, ...fns) => {
    let noOfOccurrences = -1; // we're starting with -1 here, so we don't need to re-calculate for use with index
    let timeout;

    return (ev) => {
        if (ev.keyCode !== keyCode) {
            return;
        }

        noOfOccurrences  = 1;
        clearTimeout(timeout);

        if (fns[noOfOccurrences]) {
            timeout = setTimeout(() => { fns[noOfOccurrences](ev); noOfOccurrences = -1; }, 500);
        }
    }
}

Now you have a general function that takes a key code and a number of functions. The last part is variable. So you can also pass 4 or 5 functions. It returns another function that you can then use as event listener.

const fn1 = (ev) => console.log(`key ${ev.keyCode} was hit once.`);
const fn2 = (ev) => console.log(`key ${ev.keyCode} was hit twice.`);
const fn3 = (ev) => console.log(`key ${ev.keyCode} was hit three times.`);

document.addEventListener('keydown', debounceKeyPress(32, fn1, fn2, fn3));

You can play with the time parameter of the setTimeojut function a bit to see how long or short it actually needs to be. It is also possible to include that as a param of your helper function debounceKeyPress to get more flexibility.

Hope that works for you.

Cheers. A.

  • Related