I have a webpage which has many links (mostly mailto but I don't think that's relevant), where accessibility is a priority. Due to the formatting, when the tab key is used to move around the page, the currently selected link is often off the bottom of the screen, because only the very top of the containing card is visible: the built-in autoscroll of the browser doesn't scroll far enough. How can I get the currently "selected" (highlighted with the tab key) element so I can control the scrolling manually?
To get the currently focused element of the page you can use
document.activeElement
You can use document.activeElement.id
document.activeElement gives a reference to the current active element. You can use this just like what an element query returns (document.querySelector())
How can I get the currently "selected" (highlighted with the tab key) element so I can control the scrolling manually?
If you may know which element is currently focused with the tab key (using document.activeElement), you also have to take care of the automatic scrolling performed when using a screenreader or any other assistive technologies (eye tracking device, for instance).
The fact that your scrolling relies on javascript detection of standard keyboard/mouse events or standard element activation might be problematic when using assistive technologies.
Relying on the built-in autoscroll, while not your solution, is however the best solution.
Related
I am building a modal plugin and I would like to be able to set focus to the address bar.
I'd like to be able to do this because I need to be able to restrict tabbing to objects inside of the modal window, but keyboard users and accessibility users should be able to tab out of the modal window to the address bar when they have reached the final element (so that they are not stuck inside the modal). I'm aware that I can do this by setting all of the tabbable elements outside of the modal to have a tabindex of -1, but I'd like to avoid that solution if possible.
I'm aware that it may not be possible to directly set focus to the address bar due to security restrictions. Is there, however, a way to either do this, or defocus the page so that the next element is the address bar?
Having a modal element does not remove the other elements from the visual buffer. A screenreader may read automatically any other element after your modal. So removing the tabindex of elements which might be announced is indeed not a solution.
You may try to remove the focus from any other element using some code like $(".outside_modal").onfocus() {$("#modal-first-link").focus()} but you will have incoherence between your visual focus which will read link targets and the action provided by the keyboard focus.
The only viable solution is to set the modal element in the last position of your DOM.
I have containers with multiple lines but only the first one visible (overflow:hidden). The container is expandable upon a click. (See https://stackoverflow.com/a/6972830 and the jsFiddle http://jsfiddle.net/JUtcX/2/)
If someone performs a Ctrl+F with text from the non-visible lines, the browser reports a match but cannot show it (because it's hidden).
How can I react to Ctrl+F and open the container whether a non-visible text in it was searched for?
[Update]
Approaches that do not meet all requirements:
Listening for Ctrl+F.
I have multiple containers and only want to expand those containing the search phrase. Upon listening for Ctrl+F I could only open all containers at once.
Does not work on all systems. This is a negligible defect only, though.
Chrome-specific workaround (link)
At least also Firefox should be supported
You can do something like this:
function find(e) {
if (e.ctrlKey && e.keyCode == 70) {
document.getElementById("hide").style.display = "block";
}
}
document.addEventListener('keyup', find, false);
#hide{
display: none;
}
<div>
ASDF:
<div id="hide">
Hidden
</div>
</div>
Listening to browser Ctrl+F/find layout modifications
I don't think it is possible to listen to those layout modifications.
When the browser find an element, it is equivalent to call
scrollIntoView for the matched element. Thus a scroll event will be
fired only if the container div is scrollable.
In the example, the parent style is overflow: hidden;. Thus it does
not trigger any scroll event.
It becomes then impossible to listen to these layout change, because
the only workaround that exist to listen to scroll event on
overflow:hiden element, is to listen to mouse wheel event ...
The bad story is that it is then impossible to prevent user from
modifying layout through the browser find, because even if one can
prevent Ctrl+F or F3, we can't prevent user from using the Edit-> Find
menu in Firefox or IE
JBE
Listen for Events from Browser "Find" Window in JavaScript
I don't know of any way you can listen for a find-like event and if
that's supported in any browser it sure isn't a portable solution.
I also don't know what you're trying to achieve but I think that your
best option is to listen for the keyboard events that trigger the find
window and attempt to cancel them while attempting to emulate the
find-toolbar/window with JavaScript of your own. This is however a
herculean (and nearly impossible) task due to some browsers
customization of keyboard shortcuts depending on the localization (for
instance, in IE, en-US uses Ctrl+F (for Find) while pt-PT uses Ctrl+L
(for Localizar, meaning find)).
Conclusion: I think you're out of luck there...
Miguel Ventura
Searching for text (Ctrl+F) across hidden spans
Chrome search feature (ctrl+f) finds hidden text ( but it's invisible! )
I have a problem with deep linking. I have a single page site, in which I have many small boxes and a single big boxes, that is the 'active' content. Clicking on a small box, I clear the innerHTML. Wtart an animation, the clicked become the active content, then I replace the innerHTML($('element').html('new content')) with the new content.
My question is: there is a way to deep link this process, to have:
mysite.com/firstcontent (or something similar) and have the right content active, without have to write a mega-switcher? have I to replace all with AJAX?
Typically this is handled by changing the hash (test.html*#foo*) in the window.location.
You can do this in conjunction with the hashchange event and window.history.pushState / replaceState You will need some sort of shim for older browsers. There is a jQuery plugin that will supposedly handle this for you.
I'm not hopeful, but I'll ask just in case.
I would like to be able to use JavaScript to open a select element in mobile Safari for iPhone/iPad.
An extensive Google / Stack Overflow search shows that a lot of people would like to be able to do this in browsers in general, but it is not supported (why not, I wonder?). Various hacks have been suggested, from calling focus() on the select element and changing its size property to make more option elements visible, or constructing an entirely mock select element with <div> and <ul> elements. I would, however, like to use the native browser select controls in iPad and iPhone.
I wondered, just maybe, someone might know of a proprietary Apple WebKit method to do this. It would be something like:
var myselect = document.getElementsByTagName("select")[0];
myselect.open(); // this method doesn't exist
As a bonus, it'd also be handy to know of a boolean property that says whether the select element is currently open/active, or not (i.e. not just whether the element has focus). I know I can work this out by tracking click and change events, but a simple property would be useful.
Wishful thinking?
UPDATE:
I don't yet have the answer, but I've found that simulating a mousedown successfully opens a select element in Google Chrome, but not iPad or Firefox and so on:
function simulateMouseEvent(eventName, element) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent(eventName, true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
element.dispatchEvent(evt);
}
simulateMouseEvent("mousedown", select);
UPDATE:
I've asked a related, but different (and similarly unanswered!) question on select boxes here: Is there a DOM event that fires when an HTML select element is closed?
I have a working solution for this that works on recent versions of iOS and Android. I haven't yet tested on older versions. There are no two ways about it: this solution is a hack. But it works if implemented carefully.
In my situation I had iOS 7 like toggle switch element. I wanted the picker view for the select to be presented when the switch was turned on. In my case we did not need or want the user to see the select field itself. We merely wanted to use iOS' nice scrolly-picker interface.
I used CSS to position and stretch the select completely over the switch. I then set the opacity in CSS to something like opacity: .001; which makes it invisible for all intents and purposes. It may still work with opacity 0 but I felt leaving a little opacity there may be safer and you really can't see it all anyway. Now when the user taps the area of the screen that is displaying the switch the tap events are actually going to the select which causes the picker view to display.
On the onchange event of the select I set display: none; to completely hide the select. This means that when the user touches the switch to turn it off they are interacting with the switch itself. When the switch is toggled off I then set display: block to return the select to its active state.
My use case is narrow but the position/opacity technique should be adaptable to many use cases though you may have to have 2 select elements in cases where you want the field to be visible.
Here is a screenshot demoing the technique. The opacity is set to 0.25 in this screenshot for demo purposes. When you set it to 0.001 you can't see the select
Triggering HTML controls with JS is a very gray area, partly because of security reasons, and partly due to lack of support. Even using frameworks like jQuery, you cannot simply click() a link to follow it in the same way as click() on a button - you need to trigger a native click event at the browser level (I believe the latest version of Selenium does this, but that's a testing framework so unsuitable for this problem). Congrats on being able to achieve a partial result in Chrome! However, you will not find a universal solution that uses real select inputs.
I would suggest using a different type of control - either a vertical stack of buttons if you want to press one to activate a feature, or a stack of radio buttons backed by labels (with a little CSS) if you want a multi-choice format.
The select element needs to be visible.
If you use jQuery you can do it as follows:
$('mySelectElementSelector').focus();
On mobile it will show the default select control. On desktop just focus on the select control.
Have you tried the change() method?
I have some questions about focus in general (adhering to WC3 format, screw IE). I'm having problems with unintended actions occurring on a widget i am building (using the Dojo Toolkit), and i believe a better general understanding of focus will allow me to solve my problem myself, so here goes:
First of all, which common HTML element are and AREN'T focusable? I've been trying to throw focus around and it works sometimes, and doesnt work other times...
What is the 'highest' level focusable on a page? For instance, can i focus the window? The <body> tag? Specific to dojo, can you focus an entire widget? If the template is widgeted can you focus just highest level of the template (usually a <div>)?
Can focus be 'removed'? Can i remove focus from all elements/objects on the page until the next object is focused? Can i prevent a element from being focusable (like a button)?
What are all the methods through which i can affect focus? Besides calling the focus() method on elements, can focus be set through HTML attributes or in a CSS?
Thanks in advance for what i hope to be some great answers!
Disabled controls can't receive focus according to the HTML4.01 spec
Firefocus, an extension that works over Firebug, could be a great enhancement if you're asking this sort of questions :) Install, restart and look at the Console
Related to focus is the order in which elements are given the focus, that is the order of tabbing navigation and the tabindex attribute with its values -1, 0 or positive when it exists
Any DOM element can receive focus amongst other some event handlers.
See answer 1.
Focus is passed around and not removed.
Focus can only be set by the DOM using JavaScript.
You can also use dojo.place to put things in the correct for focus.