Skip to content
Advertisement

focus() on element triggers keyup event

Can someone explain to me, why calling the focus() method on an element, triggers that elements keyup event, when the focus() method is called from an click event handler, but that handler is triggered by a keypress?

document.getElementById('testButton').addEventListener('click', e => {
  document.getElementById('modal').focus();
});

document.getElementById('modal').addEventListener('keyup', e => {
  alert('Modal element triggered!');
});
<div id="modal" tabindex="-1">Some content here</div>
<button id="testButton" type="button">Focus on content</button>

Above is an example, that you can try out yourself. The expexted behaviour for me is, that when clicking or hitting enter on the #testButton element, it will simply set focus to the #modal element. If you click the #testButton, it works, but if you press the Enter key on the #testButton as you would do if navigating the page using a keyboard, it does not work as expected. What it actually does, is that, but it also triggers the keyup event on the #modal element. I have tried to add .stopPropagation(), .preventDefault(), and .stopImmidiatePropagation() to the click event handler on #testButton, but they dont solve the problem.

Is there something I am missing completely, or is this really how it’s supposed to behave?

Advertisement

Answer

if you press space or enter when focus on a button, (keyevent, click) – both event will be triggered.
it just browser default behavior.

details.

  1. you focus on the button,
  2. you keydown-enter and this will trigger click event.
  3. focus to “#modal” before you keyup-enter
  4. then keyup event will triggered when you keyup-enter

suggest 2 ways.

    • check whether it is clickevent or keyevent with event.detail

document.getElementById('testButton').addEventListener('click', e => {
  if (e.detail != 0) {
    document.getElementById('modal').focus();
  }
});

document.getElementById('modal').addEventListener('keyup', e => {
  console.log('Modal element triggered!');
});

document.getElementById('modal').addEventListener('focus', e => {
  console.log('focus!');
});
:focus {
    outline: 3px solid #3f3;
}
<div id="modal" tabindex="-1">Some content here</div>
<button id="testButton" >Focus on content</button>
    • just prevent event.

document.getElementById('testButton').addEventListener('keydown', e => {
  e.preventDefault();
  
});

document.getElementById('testButton').addEventListener('keyup', e => {
  if (event.keyCode === 13) {
    e.preventDefault();
    e.stopPropagation();
    document.getElementById('testButton').click();  
  }
});

document.getElementById('testButton').addEventListener('click', e => {
  document.getElementById('modal').focus();
});

document.getElementById('modal').addEventListener('keyup', e => {
  console.log('Modal element triggered!');
});

document.getElementById('modal').addEventListener('focus', e => {
  console.log('focus!');
});
:focus {
    outline: 3px solid #3f3;
}
<div id="modal" tabindex="-1">Some content here</div>
<button id="testButton" >Focus on content</button>
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement