Prevent html input focus being lost to the body tag

Viewed 1836

When I have focus on the input field and I click in any open area of the body, the body becomes the document.activeElement , Is there a way to prevent the body focus completely. What I am looking for is :

  1. To prevent focus the body and maintain focus on the input field.
  2. To avoid the firing of the blur event on the input field.

I've tried adding tabindex=-1 but I believe its for Tab functionality and hence does not work in this case.

document.querySelector("#inpdontlosefocus")
  .addEventListener("blur",function(){
    
  const $log = document.querySelector("#log");
  $log.innerText += "\r\nLost focus";
})
html,body {
  width:100vw;
    height: 100vh;
}
<body id="notokaytogetfocus">
  <input id="inpdontlosefocus" type="" placeholder="dont lose focus to body">  
  
  <input id="inpokaytofocus" type="" placeholder="allow focus">  
  <div id="log"></div>
</body>

2 Answers

I'd added more html elements for a more accurate demonstration, the logic here is if the event source in body is not focus-able then we set focus back to the input we want, other wise the its a focusable element thus will get the focus(e.g. button, link, input, ...); notice that click event is attached to body and clicking outside body won't have this behavior.

document.querySelector('.notokaytogetfocus').addEventListener("click",function (e){
  if(e.target == document.activeElement){
    console.log("focusable element");
  }else{
    console.log("not focusable element");
    // we'll set foucs on desired input
    document.querySelector("#inpdontlosefocus").focus()
  }
})
.notokaytogetfocus{height: 100vh; width:100vw;}
<div class="notokaytogetfocus">
  <input id="inpdontlosefocus" type="" placeholder="dont lose focus to body">  
  <input id="inpokaytofocus" type="" placeholder="allow focus"> 
  <button>do!(focusable)</button>
  <p>lorem ipsum</p>
  <div>some text</div>
</div>

Here is a solution that will always keep the focus on input fields in your document:

  • you will be able to switch the focus between input fields.

  • if you clicked outside an element that is not input, it will get the lastest input blurred and will apply focus on it.

var blurred, focused;
const $log = document.querySelector("#log");
var els = document.querySelectorAll('input');
Array.prototype.forEach.call(els, function(el) {
  el.addEventListener('focus', function() {
    focused = this;
  });
  el.addEventListener('blur', function() {
    $log.innerText += "\r\nLost focus;"
    blurred = this;
  });
});

document.addEventListener("click", function(e) {
  e.preventDefault();
  if (focused && focused.tagName == "INPUT") {
    $log.innerText += "\r\nactiveElement= " + document.activeElement.id;
    focused.focus();
  } else if (blurred) blurred.focus();
})
html,
label {
  width: 100%;
  height: 100%;
}
<body id="notokaytogetfocus">
  <input id="inpdontloosefocus" placeholder="dont loose focus to body">

  <input id="inpokaytofocus" placeholder="allow focus">
  <div id="log"></div>

</body>

Related