Question

So I have the following function. What it does is listens for the focus event on all elements. If that element is either in $mobileMenu or $menuItems it permits it otherwise it removes the focus:

var $body = $("body");
var $mobileMenu = $("#mobile-menu");
var $menuItems = $("#main-menu a");

$body.on("focus.spf", "*", function(e){
  e.stopPropagation();
  $this = $(this);

  // Prevent items from recieving focus and switching view
  if (!$this.is($mobileMenu) && !$this.is($menuItems)) {
    $this.blur();
  } else {
    console.log(this);
  }
})

The issue I have is that this prevents the user from focusing on anything whatsoever if a normally focusable element that is now non-focusable precedes any of my white-listed elements as it just attempts to refocus on the same element over and over again.

Does anyone know how I can tell it to instead skip to the next focusable element?

Was it helpful?

Solution 2

This works (updated) :

$body.on("focus.spt", "*", function(e){
  $this = $(this);
  if (!$this.is($mobileMenu) && !$this.is($menuItems)) {
    $this.blur();
    var next=$this.nextAll().find('a,input');
    if (next.length>0) next[0].focus();
  } else {
    console.log('ok',this);
    e.stopPropagation();
  }
})

(updated) fiddle -> http://jsfiddle.net/CADjc/ You can see in the console which elements that receives focus (main-menu a and mobile-menu)

Tested on :

<input type="text" tabindex="1" value="test">
<span><input type="text" tabindex="2" value="test"></span>
<div><input type="text" id="mobile-menu" tabindex="3" value="mobile-menu"></div>
<div><span>
    <div id="main-menu">
        <a tabindex="4">main-menu</a>
        <a tabindex="5">main-menu</a>
    </div>
</span></div>
<span>
<input type="text" tabindex="6" value="test">
</span>

OTHER TIPS

If you set the tabindex to -1 on the element, it will ignore the tab.

Not sure if this works in all browsers but it works in Google Chrome.

<input type='text' value='regular'/>
<input type='text' tabindex="-1" value='with tabindex set to -1'/>

If you make something disabled, it won't receive focus. For example:

<input type="text" disabled="disabled" />

Do add it programmatically, you could do:

var el = document.getElementById('disableme');
el.setAttribute('disabled', 'disabled');

attr("readonly","readonly"), prevent input focus and value ARE send to the server.

CSS-only solution from one of my past projects

/* Prevents all mouse interactions */
.disabled-div {
  opacity: 0.5;
  pointer-events: none;
}

/* Prevents all other focus events */
.disabled-div:focus,
.disabled-div:focus-within {
  visibility: hidden;
}
<h1>CSS Only Disable with Prevent Focus</h1>

<input placeholder="Normal text field">
<br><br>
<input class="disabled-div" placeholder="Disabled text field">
<br><br>
<input placeholder="Normal text field">
<br><br>
<input class="disabled-div" placeholder="Disabled text field">
<br><br>

Flickers slightly when it receives focus. That is because when it receives focus, visibility is set to 'hidden' and focus is lost and visibility is set back to 'visible' again. This is actually good because the user now has some idea where focus is while going over disabled fields...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top