How to force "keyboard navigation" mode when programmatically setting :focus-visible - javascript

I am working on an advanced search feature for a web project in React using the Algolia React Instant search package.
I am struggling a bit with keyboard navigation.
The search result features a long list of articles with various URLs. The list is very cumbersome to navigate only with the tab-key, so I have implemented navigation with the arrow-keys that works really great.
However, I have stumbled upon an issue I am unsure how to solve regarding focus-visible. When navigating with arrow keys a function inside the component will set focus using element.focus();
If I focus the search field with the mouse and start navigating with the arrow keys the focus-visible outline is missing. However, if I navigate to the search field with the tab key and start navigating with the arrow keys the focus-visible outline is visible.
This is according to specs, as focus() will not change to focus-visible and the last navigation was done with the mouse.
But this makes it impossible to navigate with the keys - you have no idea what element is in focus. Any idea how to force the browser into thinking that I am navigating with the keyboard when setting focus programmatically?

I ended up rethinking my styling and using a focus style.
But the behavior in Chrome is really weird.
If I set a style like focus:not(:focus-visible) it will be styled with the focus style when navigating with the mouse on focus, but not if I set focus with Element.focus() (and the focus was initially set on the active element with the mouse);
So the Chrome browser knows this was not navigated by a mouse? This makes absolutely no sense to me?

Related

How to prevent formula touch event in MathJax?

How can I prevent formula touch event in MathJax? e.g. when I touch or click a formula rendered by MathJax It is gone to surround by a blue border as a response that it is touched.
This is an Example form MathJax test folder.
I have already set showMathMenu: false but I am unable to prevent this.
The outline is part of the standard browser interface for focusable items on the page. In version 2.6, MathJax added support for users using assistive technology, and that included making the MathJax menu accessible to keyboard users and those with screen readers. In order for that to work, the math expressions need to be able to accept the browser focus (so that keystrokes will be targeted to them, so the menu can be opened).
The outlines you are seeing are the focus highlighting that is the default styling for focused items in the browser (the actual effect differs between browsers, but all browsers should provide some form of visual indication for the focused item). Without that, keyboard users will not be able to know when and which math expressions are selected for keyboard focus. Removing that would make it harder (or impossible) for those users to properly interact with MathJax and its menus.
While you certainly could add CSS to your page to remove the outlines, it would be a mistake to do so, unless you have no concern for those users who require assistive technology to support their reading of your pages. You should note that all focusable elements should get these outlines (buttons, menus, input areas, etc.) when you click on them. For example, the editor I'm typing into right now has a blue outline indicating that it currently has the keyboard focus. This is part of the standard interface for focusable items, and is not something you should try to disable.

How can I get a WKWebView to show the keyboard on iOS?

My iOS app uses a WKWebView with contenteditable = true on a specific div. I'd like to have code to make the keyboard show up for the web view, so the user can just start typing. Things I've tried that have had no effect:
Telling the web view to becomeFirstResponder (a long shot, because the web view wouldn't know what div to use).
Injecting JS to tell the div to focus(). (This works in other browsers, but sadly not in WKWebView)
Simulating touch events in JS via TouchEvent and dispatchEvent() in the hope of making it seem that the user had tapped on the div.
In the third case I also used addEventListener() to observe the simulated touches and compare them to real touch events from tapping the screen. It looks like the key difference is that the event's isTrusted value is false for the simulated touches.
I get that it's a potential security issue to let apps simulate touch events, but I didn't have any other ideas. I'm trying to get the keyboard to appear, what the user types is up to them and not something I want to mess with. Basically I want the same thing as calling becomeFirstResponder() on a UITextView.
This is very similar to a WebKit issue 142757 but I haven't figured out how to use the suggested workaround linked from there.
Clarification: I can set up and use an editable web view, but the keyboard doesn't appear until I tap on the web view. I'm trying to make the keyboard appear automatically, without requiring a tap to initiate editing.
I tried this in an iPad playground, and it works without any action on my part. It’s possible there is another view that is capturing touches, or “contenteditable” is misspelled, or something else?

How to prevent the keyboard on Android browsers from changing the height of the page?

When clicking on an an input type=text, a keyboard comes up. Unfortunately, that changes the height of the web page, so that all the thinks that were "stickied" to the bottom of the page want to come up above the keyboard.
And, in my case, the element that's anchored to the bottom of the page (e.g. the Apply button below) ends up covering the next input element (e.g. Max textbox), so that when the user presses Next on the virtual keyboard, you can't see it at all because the button is still covering it.
My question is whether there is any way to prevent the keyboard from changing the height of the page?
P.S. On iOS it works like you would expect. Bringing up the keyboard doesn't change the dimensions of the page.
It is default behavior on Android devices. As I know, you can not prevent this.

Scroll to Focused Field Cordova

My Issue
I am currently in the process of writing an application for iOS using Cordova. I have a page with a form on it like so:
When the user taps on a field, the keyboard appears as expected on iOS. However, to prevent my app from moving off the screen, I have enabled the following setting:
// Prevent the keyboard from pushing up the webview
cordova.plugins.Keyboard.disableScroll(true);
Unfortunately, this prevents a few things that are causing me issues:
When a field is focused, the screen does not scroll to that field so sometimes, the field appears behind the keyboard.
Even if I did have a solution to the above, for the elements that are at the bottom of the screen, I will not be able to scroll down far enough to bring them into view above the keyboard.
My Question(s)
Solution 1
Is there any way, in Cordova, to auto scroll to the focused field without moving the whole app off the screen?
If it is possible, then how can I handle fields that are close to the bottom and cannot be scrolled up any further into view?
Obviously, the first point can be achieved using JavaScript/jQuery and some clever logic with the keyboard_height, position() and scrollTop(). But, this then creates the issue with the second point about the input fields behind the keyboard...
Solution 2
If I apply the following code, it will fix the issue highlighted above, but it will create another issue (explained below):
// Enable the auto scroll when the keyboard is shown
cordova.plugins.Keyboard.disableScroll(false);
Is there anyway to fix my header (the 'Edit Profile' bit), to the top of the screen to ensure that part is always visible?
Use https://www.npmjs.com/package/cordova-plugin-keyboard#keyboardshrinkview and its Keyboard.shrinkView method.

Proper touch button behavior for MobileSafari

MobileSafari as a rule has incorrect HTML button behavior (incorrect meaning: "not like an iOS native button"). Correct button behavior is as follows:
User touches button: Button highlights
User drags finger out of button: Button dims
User drags finger back into button: Button highlights
User drags finger out of button and releases: Button does not click
MobileSafari buttons highlight when you touch them, stay highlighted no matter where you move, and click no matter where you release them (unless the view scrolls, in which case the touch is always canceled, even if you re-enter the button).
This problem applies to all clickable things such as links (when -webkit-touch-callout is set to none). I have only found one web application so far that has correct button behavior: Facebook. Looking at their code for it, it looks like they've done quite a lot of jumping-through-hoops to make it work correctly (tracking all the mouse events manually and not using buttons at all). The code is dense, uses Javelin, and I'm not yet clear on all the pieces required to make it work.
I know I'm somewhat kidding myself (since if it were easy, everyone would do it), but I'm going to ask anyway. Is there any generally-available piece of code that handles this feature? Is there a simpler solution than reverse engineering Javelin, even if it is only applicable to WebKit? (Javelin isn't very-well suited to my lightweight needs.) My ultimate goal is correct button behavior for a UIWebView embedded in a native app, so hybrid JavaScript/ObjC solutions are acceptable as well (though no hybrid approaches come to mind).
Basically what you'd want to do is build out some sort of hybrid hover functionality for touch devices, which detects when your finger moves in/out of the button in question.
I built a basic JSFiddle which implements some barebones functionality. If you know any javascript, I think you'll get the idea.
Live JSFiddle DEMO
Try it on your iOS device (and maybe your Android device??).
-
brian

Categories