问题
I have the following requirements:
On my webpage there are anchor links for navigation (thinks like skip to content
etc.). These anchors are supposed to bring the target element into view and focus it. (Focus is important, because else screenreaders don't get positioned correctly. so far my code looks like this:
<a href="#content" class="navbtn">Skip to content</a>
<!-- somewhere else...-->
<div id="content" tabindex="-1">
Lorem ipsum...
</div>
<script>
$(".navbtn").click(function(e) {
e.preventDefault();
$("#content").focus();
});
</script>
Please note that I'm aware this is hardcoded and I'll change that in the future, but for test purposes I left it to this.
OK, so what does this do? In this post the method above was said to focus the div element. Visually I cannot judge, but my screenreader won't move to the element (I'm using VoiceOver in Safari on an iPhone). If the target is a button, a link or any other element which has a tabindex by default, it works fine.
Any ideas?
EDIT: I got it to wolk with my braille display when pressing the left mode key. I usually use the right mode key to send a double tap event to the phone, but the right one doesn't work. The left one, however, does. I don't know why, to be honest. Double tap onscreen still doesn't work... Either way, no JavaScript needed.
回答1:
I've just tested the following (with no JavaScript) on an iPhone running iOS12, with VoiceOver in Safari:
<a href="#content">Skip to content</a>
...
<div id="content" tabindex="-1">Target content...</div>
It worked as expected, with focus moving to the target content and VoiceOver announcing "Target content...". Can you describe the steps you're taking when you test in more detail?
回答2:
You're doing too much work. By default, an <a>
will move the focus for you. However, if the destination element is not a natively focusable element, then it must also have tabindex="-1"
for some browsers (mainly Internet Explorer). See "Accessible HTML Elements" in "About Active Accessibility Support" for the reason why.
So your above example will work with simply:
<a href="#content" class="navbtn">Skip to content</a>
<!-- somewhere else...-->
<div id="content" tabindex="-1">
Lorem ipsum...
</div>
No javascript is needed. You can test it by using the keyboard to tab to the "Skip to content" link then pressing enter. If you then press tab again, the focus should move to whatever focusable element is after your <div>.
If you then shift+tab, you will not go back to the <div> (which is the behavior you want) because it has tabindex="-1"
instead of tabindex="0"
.
I use this pattern all the time in my accessible websites.
However (and this is a big "however" and I think is the main point of your question), VoiceOver on iOS (not sure about the Mac) will not honor the focus change. That's a bug (in my opinion) with Apple. Go to any website that has in-page links and the VoiceOver focus won't move the destination element. You can see one reference to this problem at https://www.applevis.com/forum/ios-ios-app-discussion/skip-link-issue
Unfortunately, you should write your code using the simple example (no javascript required) and VoiceOver users on iOS will continue to have a problem like they have on all other sites.
回答3:
Use tabindex="-1" on the div instead of tabindex="0". It will make the div programmatically focusable, whereas tabindex="0" makes it user focusable (as someone uses the tab key to move through the content). More on Using the tabindex attribute
回答4:
Voiceover on iOS will not honour JavaScript focus changes on most elements that aren't natively focusable regardless of setting tabindex="-1" or tabindex="0". If you need to have shifting focus for iOS then what I have done is add an empty tag and set the focus to that, it's not the best solution but it's the only one available on iOS for now.
回答5:
This would always be best:
<a href="#content">Skip to content</a>
...
<div id="content" tabindex="-1">Target content...</div>
But sometimes you need some extra functionality so I add a keypress to make sure it triggers a click. Keycode 32 is for the space bar and the 13 is for the enter key.
$(".navbtn").click(function(e) {
e.preventDefault();
$("#content").focus();
});
$(".navbtn").keypress(function(e){
if(e.which == 32 || e.which == 13 ){
$(".navbtn").click();
}
});
Or you can just have the keypress trigger the focus
来源:https://stackoverflow.com/questions/53978096/best-way-to-focus-element-of-any-kind