Android browser does not update DOM while keyboard open - javascript

I have a textarea element on a web page, with some JavaScript code which executes on certain keyboard events; among other things the JS code should make some visible updates to the page.
On desktop browsers, and also on iOS this works fine, however on the stock Android browser (Samsung Galaxy S3 running 4.0.4) none of the page updates occur until the onscreen keyboard is closed. The page updates seem to get 'buffered' and once the keyboard closes they all run in quick succession.
I know the event handlers are running while the keyboard is open, because if I insert some alert statements into them then the alert dialogs appear with each keypress rather than waiting for the keyboard to close.
Does anyone else seen this, or know of a workaround?

Related

Prevent soft keyboard closing on text input blur

I am building a Web chat application (PWA).
I have a chat input, which I would like to keep focus on even when the "send" button is clicked. So I want the keyboard to stay open even when a chat is sent, either by pressing a "send" button, or by clicking on the "send" in the mobile's keyboard itself. This is the behavior you get in messaging apps like Whatsapp, iMessage, etc.
Even though it works on Android as expected, but I can't make it work on iOS Safari / Chrome.
What I have tried so far is as follows:
Bind touchstart / mousedown event, call preventDefault and stopPropagation.
Additionally, I am also doing "preventDefault" on the click event.
How can I achieve this on iOS Safari with vanilla javascript + HTML?

Chrome Window Randomly Disables Key Commands and Events

I am in the process of developing a data visualization; however, I have run in to a problem that appears (seemingly randomly). When the page is first loaded, sometimes chrome will 'lock up'; The chrome toolbar will disable all command keys (ie copy, paste, select all...) and events will be incorrectly triggered (mouseover events get triggered on click, click events are triggered on double click, etc...)
I have already tried opening and closing the inspector window, searching for a memory leak, and trying to identify any infinite loops in my code.
I'm running a local http server via python 3, accessing the page via google chrome on macOSX, but I'm not sure if any of that may be related.
Edit: I found that clicking on another application other than chrome and then clicking back on chrome fixes the issue; however, I'd ideally want our user to not have to do that.

Can't focus elements on load in Chrome - very weird bug (in Chrome?)

I have a very, very weird issue that only seems to be an issue in Chrome.
When a user comes on the website, the user cannot focus any element (via mouse click, if they focus it via tabbing, the elements don't get the 'focused' state either) and that's only an issue in Chrome. That is, until the user resizes the window, minimizes the window, opens a new tab, opens developer tools, etc. Reloading the page does nothing. However, as soon as focus is "enabled", the user can navigate/refresh with purging cache, etc., close the browser and open it again, and everything works normally - the elements get the 'focused' state normally.
This behaviour can only be reproduced in Chrome and not on localhost.
The difference between localhost and beta environment is:
beta env requires authentication (basic http auth)
files in development env are concated in a single JS and single CSS file and both are minimized
beta env includes hotjar, while there's no hotjar on localhost
There are no custom event listeners that would listen for the 'resize' event. There are no errors in console and all javascript that doesn't depend on focused element state gets executed correctly. Hover events and all CSS styling that depends on hovered state all work correctly.
The main issue is, that a form which has to be filled out and includes a datepicker, cannot be filled out and thus the users can't really interact with the page. Datepicker doesn't open and, as the input elements don't get the focused state, they don't visually change (CSS :focused selector isn't working either) and thus give the impression to the user that they cannot type in the normal text inputs (which works, after clicking on the input, it is possible to type in the input).
I have tried removing hotjar and the problem persisted. The only thing that made the problem go away was removing the basic auth, however, that is not an option in this stage (it's a closed beta test, so we need to limit the access only to the users with password).
I also find it extremely odd that basic auth would interfere with the focused state of elements, especially as the error persists after you refresh and only goes away as soon as you interact with browser itself (minimize, open new tab, do anything that resizes your browser window or document), after that it works correctly and there are no errors whatsoever.
The problem only started to appear recently, but I do not believe it's an issue with the app itself, as I tried rolling back to a couple months old build and the problem persists. All of that makes me believe it's a bug in Chrome, but what can be done to fix it?
EDIT: I also tried to add autofocus property to an input element and, in beta environment, it doesn't get focused.
So it seems it indeed is a Chrome bug that's present both on mobile (Android and iOS) Chrome browsers, as well as desktop Chrome browser (tested both on a Windows and a Mac). I submitted an official bug report. In the bug report, a fellow user made a website that's accessible only through basic auth and only has 2 basic inputs, the input should get a red border on focus. As expected, after opening the webpage in Chrome (for ease of use - incognito mode), the input doesn't get focus and the border doesn't change.
For those who are also affected by this bug in Chrome, you can track the bug progress here: https://bugs.chromium.org/p/chromium/issues/detail?id=740652
Meanwhile, here's a hacky solution for those interested:
$(document).on("ready", function() {
var $inputs = $("input");
$inputs.off("click.trick");
if (!sessionStorage.fixedChromeFocus) {
sessionStorage.fixedChromeFocus = "true";
$inputs.on("click.trick", function() {
var win = window.open("/", "_blank");
setTimeout(function() {win.close()}, 1);
$inputs.off("click.trick");
});
}
});
The goal is to, somehow, interact with the browser outside of the current page, to make it somehow lose focus. You cannot use JS to minimize browser, cannot resize it, cannot open dev tools. What you can do, though, is open a new window. Of course, if you open a new window immediately, a pop-up blocker (as most people have it) will block it and the window itself (or rather your current tab) won't lose focus. Opening a new window can only be done as a reaction to a user event (without triggering potential pop-up blocker).
I also use some browser detection so the code will only be executed for Chrome and, using server-side conditioning, only for builds that include basic auth.
What the code does, quite self evidently, is that as soon as a user clicks on an input, it opens a new tab and quickly closes it, 1ms later. To prevent this from happening all the time, on every page load, sessionStorage, which gets cleared automatically after tabs from that domain are closed, is used (and we've already established that once focus starts working correctly, it will work as long as you keep your browser open).
The effect of this code is that the user will see a quick white flash the first time he clicks on the input, but everything will work correctly

Show android keyboard from javascript

I want to be able to show keyboard on mobile browser (e.g. Android) after navigating to the page.
I have already seen some workarounds:
Show virtual keyboard on mobile phones in javascript
Can I trigger Android soft keyboard to open via javascript ( without phonegap )?
Showing Android's soft keyboard when a field is .focus()'d using javascript
But all of these examples work only if user tap somewhere. It allows to trigger focus() from within the click(). Does someone know if there any way to do the same thing but without user clicking?
I've tried to trigger click programmatically but it also not working. http://jsfiddle.net/alex_myronov/e5JcP/10/
My current answer to this is no, can't be done. The script that calls focus() click() on an input needs to be running with user context, ie. triggered by a user interaction. After fairly dedicated fiddling, I've found no way round this.
I managed to successfully open the virtual keyboard by just calling focus() method of the input.
It works in my app both on android 2.3 and 4.1.
I think the trick is that you have to wait untill the page is completly rendered before you call focus().
My app is using jquery mobile and I call focus() when the pageshow event is triggered:
$("#myPage").on("pageshow", function( event ) {
$("#myPage").find('input:first').focus();
} );
Or maybe it's working because I'm in a phonegap app?

Is there a way to see that a browser window is minimized while the user is switching to the other window on iphone?

Is there a way to see that a browser window is minimized while the user is switching to the other window on IPhone? Same about when the browser window becomes inactive by switching to any other application.
I've tried to bind to jQuery onfocus, onblur events ($(window).blur(...);) but got no callbacks.
Thanks!
I think the closest thing to what you're looking for are the pageshow and pagehide events. In tests I did in iOS 5.1, when switching to another application from Mobile Safari after double-pressing the home button, the pagehide event seemed to be fired immediately before the application actually switched, whereas if I pressed the home button just once to get to the home screen it seems the JavaScript thread is suspended immediately and listeners for the event are only called when Mobile Safari is brought into focus again.
This is how you would listen for the events:
window.addEventListener('pageshow', myPageShowListenerFunc, false);
window.addEventListener('pagehide', myPageHideListenerFunc, false);
For later versions of iOS pageshow and pagehide don't work reliably anymore. However, you can now use the visibilitychange event, which is triggered when the user opens another browser tab, or when the browser is minimised (by pressing the home button).
So your code would look like
window.addEventListener('visibilitychange', myVisibilityHandleFunc, false);
or with jQuery
$(document).on('visibilitychange', myVisibilityHandleFunc);
From MDN:
The Page Visibility API lets you know when a webpage is visible or in focus. With tabbed browsing, there is a reasonable chance that any given webpage is in the background and thus not visible to the user. When the user minimizes the webpage or moves to another tab, the API sends a visibilitychange event regarding the visibility of the page.
There is a property called document.webkitHidden that can be used for iPhones, to know if the change was visible -> hidden, or hidden -> visible.

Categories