Search code examples
javascriptjqueryonclickkeypress

Toggle audio playback on keyboard key


Here is my code for 'click'- this works perfectly fine

masterPlay.addEventListener('click',() =>{
    if (audioElement.paused  || audioElement.currentTime<=0)
    {
        audioElement.play();
        masterPlay.classList.remove('fa-circle-play')
        masterPlay.classList.add('fa-circle-pause')
        gif.style.opacity = 1;
 
    }
    else 
    {
        audioElement.pause();
        masterPlay.classList.add('fa-circle-play')
        masterPlay.classList.remove('fa-circle-pause')
        gif.style.opacity = 0;

    }
})

here is my code for keypress which does not do anything.

document.getElementById("masterPlay").addEventListener('keypress',() =>{
    if (audioElement.paused  || audioElement.currentTime<=0)
    {
        audioElement.play();
        masterPlay.classList.remove('fa-circle-play')
        masterPlay.classList.add('fa-circle-pause')
        gif.style.opacity = 1;
 
    }
    else 
    {
        audioElement.pause();
        masterPlay.classList.add('fa-circle-play')
        masterPlay.classList.remove('fa-circle-pause')
        gif.style.opacity = 0;

    }
})

Please tell me the correct logic for the 'keypress' to work


Solution

  • You're assigning a key listener to a specific element - which means it has to be focused in order to work. The best is to use a <button> element, and is needed use .focus() to focus it on DOM ready:

    const elPlay = document.querySelector("#play");
    const elAudio = document.createElement("audio");
    elAudio.src = "//upload.wikimedia.org/wikipedia/en/3/39/Metallica_-_Enter_Sandman.ogg";
    
    const masterToggle = () => {
      elAudio[elAudio.paused ? "play" : "pause"]();
      elPlay.classList.toggle("fa-circle-play",  elAudio.paused);
      elPlay.classList.toggle("fa-circle-pause", !elAudio.paused);
    };
    
    // Do on button click or on "Space" key (if button is focused):
    elPlay.focus();
    elPlay.addEventListener("click", masterToggle);
    #play.fa-circle-play::after{ content: "Play"; }
    #play.fa-circle-pause::after{ content: "Pause"; }
    Click or press Space to toggle play:<br>
    <button id="play" class="fa-circle-play" aria-label="Toggle audio play" type="button"></button>

    If for some reason you need to assign a specific key, you could do in on the window level, using the "keydown" Event. In that case make also sure that the user is not typing into inputs, textareas, etc:

    const elPlay = document.querySelector("#play");
    const elAudio = document.createElement("audio");
    elAudio.src = "//upload.wikimedia.org/wikipedia/en/3/39/Metallica_-_Enter_Sandman.ogg";
    
    const masterToggle = () => {
      elAudio[elAudio.paused ? "play" : "pause"]();
      elPlay.classList.toggle("fa-circle-play",  elAudio.paused);
      elPlay.classList.toggle("fa-circle-pause", !elAudio.paused);
    };
    
    // Do on button click or on "Space" key (if button is focused):
    elPlay.focus();
    elPlay.addEventListener("click", masterToggle);
    
    // Do on specific keyboard key ["P"]
    addEventListener("keydown", (evt) => {
      // console.log(evt.code)
      if (
        evt.code === "KeyP" &&
        !evt.target.closest("input, textarea, [contenteditable]")
      ) {
        masterToggle();
      }
    });
    #play.fa-circle-play::after{ content: "Play"; }
    #play.fa-circle-pause::after{ content: "Pause"; }
    Click or press Space to toggle play:<br>
    <button id="play" class="fa-circle-play" aria-label="Toggle audio play" type="button"></button>