简体   繁体   中英

Prevent browser from re-positioning focused elements navigated to via tabbing

When you navigate through form elements or anchors using the tab key (and shift + tab) the browser automatically scrolls to that focused element. If the element is not viewable because it is a part of an overflown content where overflow is set to be hidden, it moves (or scrolls) the content's container to reveal the focused element. I want to either stop or find a way to negate this behavior

Here's something I put together to showcase the issue. I reproduced it in Chrome.

https://jsfiddle.net/charlieko/wLy7vurj/2/

 var container = $("#container") var cur = 0; function go(increment) { var next = cur + increment; if (next < 0) next = 4; else if (next > 4) next = 0; cur = next var newX = cur * 500; container.css({ transform: 'translate(-' + newX + 'px, 0)' }) } $("#left").click(function(e) { go(-1); }); $("#right").click(function(e) { go(1); }); 
 body { overflow: hidden; } #container { width: 2600px; overflow: none; transition: transform 0.4s; transform: translate(0, 0); overflow: hidden; margin: 0; } li { width: 500px; text-align: center; list-style-type: none; float: left; margin: 0; padding: 0; } a { color: black; font-size: 2.0rem; } #ui { position: fixed; top: 200px; } #ui span { cursor: pointer; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="container"> <ul> <li><a href="#">Link 1</a> | ABCD EFG</li> <li><a href="#">Link 2</a> | HIJK LMNO</li> <li><a href="#">Link 3</a> | PQRSTU VW</li> <li><a href="#">Link 4</a> | XYZA BC</li> <li><a href="#">Link 5</a> | DEFG HI</li> </ul> </div> <div id="ui"> <div> <span id="left">Left</span> | <span id="right">Right</span> </div> <p> Use left and right to move. Issue: Use tab key (and shift+tab) to navigate to any of the links. The container of the links shift to show the focused link. Notice the content is decentered when it happens. </p> </div> 

The issue is that now there are two ways to slide the contents: via interacting with the left|right buttons and via tabbing through the links. When the user chooses to navigate using the tabs it messes up the sliding logic. The content is de-centered, and the index I saved in a variable no longer represents what's visible on the screen. I can handle the accessibility issue programmatically using an onFocus event, so this automatic behavior isn't helping anything.

Is there a way to stop this behavior? I already tried preventDefault() method on onFocus events on the anchor elements.

I was able to figure out a solution. What the browser does is that it scrolls the direct parent of the overflowing content to the position so that the focused element is right in the center. Simply modifying scrollLeft property of the parent element did the trick. So in the onFocus event of the link:

function onFocus (e) {
    document.getElementById('content-parent').scrollLeft = 0;
    // Code for repositioning the content itself using transform with transition animation
}

Overflow:hidden is usually good for content which is intended to scroll and move, so preventing that will be difficult. If you want the Tab control to stay only on things which are visible (including any buttons or links that update your slider), then you'll need a different method of hiding your content in addition to (or instead of) overflow.

Try display:none on your list items until they are within the open/visible part of div#container. That removes them from the DOM (and therefore from keyboard focus) until you're ready. If you create a class called 'hidden' with just display:none in it, then the only script you'll need is to add/remove the class from the list item when the Left/Right controls are used. I'd edit your code sample to demonstrate but I'm on a tiny screen right now.

The problem then is that your keyboard users can't reach the Left/Right controls. If you change those to button or link elements, then they'll have keyboard support by default in every browser. And then all your users are relying on your Left/Right controls no matter whether they're using a mouse or the keyboard, which gives you more control over how it looks at each stage.

You could set tabindex="-1" for elements that are off the screen. This is suggested by MDN.

https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex

您可以将链接的tabindex to -1设置tabindex to -1以避免集中注意力。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM