Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a "wall" on top of a div and make everything inside it not clickable and not focusable?

Imagine I have a div A, which is absolute positioned. Inside this div A, there may be several input controls. I want all of these controls to be inaccessible through click events. I also want to prevent them to be accessible through tab, that is, gaining focus. I want them to be like dead, but not visually disabled.

What is the best way to achieve that?

like image 622
André Pena Avatar asked Dec 20 '15 15:12

André Pena


2 Answers

You can prevent mouse actions with pointer-events: none:

To prevent the contents from being focusable, you can do some of these:

  • Set a negative tabindex to each element which has a tabindex focus flag set by default

    Technically the element will still be focusable, but it won't be reached using sequential focus navigation.

  • Make them inert

    However, I don't know any way do do this except with a modal dialog, which makes the entire document inert.

  • Disable each element

    Note not all elements can be disabled

  • Use JS to undo focus.

    Note the focus (nor focusin) event is not cancelable, but you can undo it with .blur().

    Since focus doesn't bubble, if you want event delegation you must listen to capture phase

    element.addEventListener('focus', function(event) {
      event.target.blur();
    }, true);
    

Example:

document.querySelector('div').addEventListener('focus', function(e) {
  e.target.blur();
}, true);
div {
  pointer-events: none;
}
<div>
  <button type="button">I am a button</button>
  <input type="button" value="I am an input button" />
  <input type="text" value="I am a text button" />
  <a href="javascript:void(0)">I am an anchor</a>
</div>
like image 129
Oriol Avatar answered Oct 24 '22 19:10

Oriol


There are a couple of ways to do it. One is to set tabindex of all the elements to -1. The other is to not worry about tabindex and just block tab if you are not in the modal.

This is the basic idea, not a full solution for allowing tabs. This allows you to see how to detect if you are in the modal to allow for tab and cancels it when you are not in the modal.

You would need to add more logic to the code to see if you are in the last textbox on the modal or if you are on the first with shift tab.

(function () {
    var allow = false,
        isModalActive = true;
    document.getElementById("overlay").addEventListener("keydown",  function(evt){
        var keyCode = evt.keyCode || evt.which;
        if (keyCode === 9) {
           allow=true;  
        }
        //TODO FOR YOU determine if the current element is on the last textbox and than you would need to loop to the first element in the textbox.   Also need to detect if it is shift tab for the first element...
      
    });
    document.body.addEventListener("keydown", function(evt){
        var keyCode = evt.keyCode || evt.which;
        if (isModalActive && keyCode === 9 && !allow) {
            evt.preventDefault();
        }
        allow=false;
    });
}());
#overlay{
  border: 1px solid black;
  background-color: #CCC;
  padding: 2em;
}
<input type="text">
<div id="overlay">
    <input type="text"> 
    <input type="text">
    <input type="text">
</div>
<input type="text">
 
like image 31
epascarello Avatar answered Oct 24 '22 18:10

epascarello