I'm writing a web app for the iPad (not a regular App Store app - it's written using HTML, CSS and JavaScript). Since the keyboard fills up a huge part of the screen, it would make sense to change the app's layout to fit the remaining space when the keyboard is shown. However, I have found no way to detect when or whether the keyboard is shown.
My first idea was to assume that the keyboard is visible when a text field has focus. However, when an external keyboard is attached to an iPad, the virtual keyboard does not show up when a text field receives focus.
In my experiments, the keyboard also did not affect the height or scrollheight of any of the DOM elements, and I have found no proprietary events or properties which indicate whether the keyboard is visible.
Only tested on Android 4.1.1:
blur event is not a reliable event to test keyboard up and down because the user as the option to explicitly hide the keyboard which does not trigger a blur event on the field that caused the keyboard to show.
resize event however works like a charm if the keyboard comes up or down for any reason.
coffee:
fires on anytime the keyboard is shown or hidden for any reason.
Note however on in the case of an android browser (rather than app) there is a retractable url bar which does not fire resize when it is retracted yet does change the available window size.
During the focus event you can scroll past the document height and magically the window.innerHeight is reduced by the height of the virtual keyboard. Note that the size of the virtual keyboard is different for landscape vs. portrait orientations so you'll need to redetect it when it changes. I would advise against remembering these values as the user could connect/disconnect a bluetooth keyboard at any time.
Note that when the user is using a bluetooth keyboard, the keyboardHeight is 44 which is the height of the [previous][next] toolbar.
There is a tiny bit of flicker when you do this detection, but it doesn't seem possible to avoid it.
I haven't attempted this myself, so its just an idea... but have you tried using media queries with CSS to see when the height of the window changes and then change the design for that? I would imagine that Safari mobile isn't recognizing the keyboard as part of the window so that would hopefully work.
Example:
You can use the focusout event to detect keyboard dismissal. It's like blur, but bubbles. It will fire when the keyboard closes (but also in other cases, of course). In Safari and Chrome the event can only be registered with addEventListener, not with legacy methods. Here is an example I used to restore a Phonegap app after keyboard dismissal.
Without this snippet, the app container stayed in the up-scrolled position until page refresh.
This solution remembers the scroll position
I did some searching, and I couldn't find anything concrete for a "on keyboard shown" or "on keyboard dismissed". See the official list of supported events. Also see Technical Note TN2262 for iPad. As you probably already know, there is a body event
onorientationchange
you can wire up to detect landscape/portrait.Similarly, but a wild guess... have you tried detecting resize? Viewport changes may trigger that event indirectly from the keyboard being shown / hidden.
Which would simply alert the new height on any resize event....