Windows 10 Tablet Browser: soft keyboard very buggy - javascript

I have a tablet html app. Some pages have <input> and <textarea> together with many other elements: links, menus, texts, ...
If I don't press any <input> or <textarea> everything works ok
As soon as I press one input element, the soft keyboard pops up (as expected).
After entering some text and hiding the keyboard, the keyboard pops up again everytime I click anywhere on the webapp (even in non-focusable elements)
This totally ruins the experience, as you are forced to use the web app with the keyboard always shown.
I have tried many different approaches to manipulate the input focus without any success, like calling blur(), focus() and related methods on the focused component, containers, window ... but seems nothing but reloading the page resets the keyboard state to keep hidden again until a focusable element is tapped.
My experiments:
Checked that pressing outside of the <INPUT> / <TEXTAREA> causes the focus to be removed: onblur() gets called, and document.activeElement returns NULL.
Also tried to manually blur() everything in the document after an onchange is triggered:$("input,textarea").blur() .
Tried to manually giving the focus() to a non-interactive element with a TABINDEX (hacky):
<div id="dummyfocus" tabindex="0">
$("#dummyfocus").focus()
I checked that the dummy element in fact receives focus, the input/textarea unfocuses, but even in this case, the problem persists.
In Android or IOS everything works as expected: Keyboard will not auto-show if no <input> or <textarea> is focused.
Any advice? Any funky microsoft-proprietary css tag I haven't heard about? :)

I have similar issue, after some digging find out that issue reproducible on Microsoft Edge browser( used in win10 uap as rendering engine).
When clicked anywhere active element becomes body element and for some reason (maybe bug) keyboard gets activated, so I added tabindex=0 on container div which is nested in body, so when clicked outside of any focus-able element that container becomes activated element and keyboard popup isn't fired.
for checking which element is activated I used this code
document.body.addEventListener('click', function() {
console.log(document.activeElement);
});
Hope this helps.

I managed to resolve this by adding the following if you are still interested. Added a dummy control to take the focus then change the focus when clicking away from the text area.
$("body").click(function () {
$("#radioDummy").focus();
});
$("#MyTextArea").click(function (e) {
e.stopPropagation();
});

It seems the issue lies in the touchstart event when using the keyboard on Windows 10. When you hide the keyboard (e.g. pressing the close button (x) on the keyboard), the input field still has focus. And when you press anywhere else, the keyboard pops up again. However, pressing anywhere for a longer time (long press) will remove the focus from the input, and not show the keyboard again. This got me thinking, that the problem could be solved hooking up the touchstart event, and prevent the event propagation, and remove the focus from the input.
I created a global #HostListener inside my main AppComponent that listens for touchstart events. When the body is clicked, stop the propagation of the event, and call document.activeElement.blur() (Loose focus).
#HostListener('document:touchstart', ['$event'])
globalTouchEvent(event) {
if (event) event.stopPropagation();
document.activeElement.blur();
}
I have created a Stackblitz that you can test using a Windows 10 tablet.

Related

Google Chrome on mobile fires additional unwanted MouseEvent on file input

I've run into some event related issues with Google Chrome (78) on mobile. I have a setup where a file input (including the label) is appended when clicking a button. The file input will replace the button entirely and will be appended in exactly the same spot as where the button originally was.
On most browsers, this works fine. However, it seems that the mobile version of Google Chrome will fire a delayed click event after the initial touch on the button, causing the click to activate the file upload dialog. This click is fired on the file input, even though the file input was not even present during the initial touch.
It's not possible to stop the propagation on the button click, since I am listening for a TouchEvent, but the additional event is a MouseEvent. I'd rather not listen to the MouseEvent just to stopPropagation to prevent any cross browser issues. PreventDefault is also not an option, since the button is located in a slider, which would break the slider functionality.
Another option is to hide the file input until an event loop has passed (setTimeout of 0), which essentially fixes the issue, but I'm hoping for a more elegant solution. Do any of you have any potential fixes for the issues?
I've set up a CodePen with a minimal code example showcasing the issue: https://codepen.io/frankderouge/pen/wvvRPRV
The basic set up is that a file input is initially hidden and then shown when a button is clicked.
//This listener is added to the 'button'
document.querySelector('.toggle_off').addEventListener('touchstart', (e) => {
//This won't do anything since we're handling a touch event, not a click event.
e.stopPropagation();
//This fixes the dialog open but would break sliding functionality
//e.preventDefault();
//Hide the button
e.target.style.display = 'none';
//Then show the file input, on which the additional event will be triggered
document.querySelector('.toggle_on').style.display = 'block';
});
Thanks in advance!
It turns out this is known as a 'ghost click', which exists for compatibility reasons and is actually 'expected behavior'. I did not expect a ghost click to occur if the mouse event was not bound to the original element in the first place, but apparently this does happen in some browsers.
The ghost click can be prevented by calling preventDefaulton a TouchEvent, in the initial post I stated that:
PreventDefault is also not an option, since the button is located in a
slider, which would break the slider functionality.
But I've recently learned that it does not matter on which 'part' of the touch the preventDefault is called on since the ghost click is always triggered after all the touch events. Therefore the issue with the scrolling being prevented does not occur if preventDefault is called on the touchend, rather than the touchstart or touchmove.
document.querySelector('.element').addEventListener('touchstart', (e) => {
//Process the touch start event
});
document.querySelector('.element').addEventListener('touchend', (e) => {
//Prevent default on the touchend, preventing the ghost click from happening
//But still allowing the users to zoom and scroll
e.preventDefault();
});

How to set focus and display keyboard in safari with jQuery

I'm trying to set focus and place the cursor in a text box and bring up the keyboard automatically when I pop up a modal dialog. I don't want the user to click anywhere. This works fine everywhere except on mobile Safari.
I tried focus(), touchstart, timeouts, direct and indirect event generation, etc. with jQuery with no luck. Does anyone have any ideas?
Try to generate a click event after setting the focus

From a click handler, how do you detect whether the click formed a selection or not?

In my application, clicking on the caption div for a window minimizes it, and clicking on the body of the window focuses the input control. However, if the user selects some text, the browser still fires the click event. How do I distinguish between click events that eliminate a selection and those that form a selection? I tried checking window.getSelection().isCollapsed but that is still set to true in the handler if there was a selection and the click clears the selection.
Is there a correct way to do this?
EDIT: This might be a Chrome bug. The behavior works exactly as I want in Firefox. See the example code here https://jsfiddle.net/tL3obf7q/
EDIT 2: Chrome bug after all! https://bugs.chromium.org/p/chromium/issues/detail?id=289763

Can I clear the focus from a touched div on a mobile?

I have a page intended for desktop and mobile that has buttons allowing the user to touch and hold them to make adjustments. This jsfiddle illustrates the behaviour.
The problem is that on my Android phone, the div acting as a button gets highlighted with focus. It will then no longer respond to touch events until the focus has been taken away from it (by pressing another button) and going back to it.
Is is possible to clear or disable the focus of elements?
Would e.preventDefault be an option?
you can try $("#id").blur(), or simply focus on something else like $("#otherid").focus()

touch equivalent of focus() method?

You can pass focus to an element in javascript as such:
element.focus()
I'm doing that with a input text box and it works fine. The input box gets focus and the cursor is in it.
We now want to also trigger the soft keyboard on touch devices. By default, putting focus on a field via JS will move the cursor into the field, but won't open the keyboard until the user physically taps on the field.
Is there a way to trigger a touch event (I'm guessing touchstart) akin to this:
element.touchstart()
That doesn't work, but hoping there is some method for this...
BTW, this is primarily for webkit. We're trying to get this working on an iPhone and BB Torch.
The event is ontouchstart instead of touchstart

Categories

Resources