views:

3097

answers:

6

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.

A: 

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:

@media all and (height: 200px){ #content {height: 100px; overflow: hidden;} }

Janae
Very clever idea. Unfortunately, in my tests, showing the keyboard did not affect the height values used to evaluate media queries.
LKM
+3  A: 

If there is an on-screen keyboard, focusing a text field that is near the bottom of the viewport will cause Safari to scroll the text field into view. There might be some way to exploit this phenomenon to detect the presence of the keyboard (having a tiny text field at the bottom of the page which gains focus momentarily, or something like that).

ianh
That's an ingenious idea. I found a similar solution that also uses the current scroll position to detect the virtual keyboard.
LKM
A: 

Well, you can detect when your input boxes have the focus, and you know the height of the keyboard. There is also CSS available to get the orientation of the screen, so I think you can hack it.

You would want to handle the case of a physical keyboard somehow, though.

stuntmouse
A: 

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.

window.addEventListener('resize', function() { alert(window.innerHeight); });

Which would simply alert the new height on any resize event....

slf
Unfortunately, in my tests, the keyboard did not trigger the resize event.
LKM
+8  A: 

I found a solution which works, although it is a bit ugly. It also won't work in every situation, but it works for me. Since I'm adapting the size of the user interface to the iPad's window size, the user is normally unable to scroll. In other words, if I set the window's scrollTop, it will remain at 0.

If, on the other hand, the keyboard is shown, scrolling suddenly works. So I can set scrollTop, immediately test its value, and then reset it. Here's how that might look in code, using jQuery:

$(document).ready(function(){
    $('input').bind('focus',function() {
        $(window).scrollTop(10);
        var keyboard_shown = $(window).scrollTop() > 0;
        $(window).scrollTop(0);

        $('#test').append(keyboard_shown?'keyboard ':'nokeyboard ');
    });
});

Normally, you would expect this to not be visible to the user. Unfortunately, at least when running in the Simulator, the iPad visibly (though quickly) scrolls up and down again. Still, it works, at least in some specific situations.

I've tested this on an iPad, and it seems to work fine.

LKM
+1  A: 

Hi there, maybe a slightly better solution is to bind (with jQuery in my case) the "blur" event on the various input fields.

This because when the keyboard disappear all form fields are blurred. So for my situation this snipped solved the problem.

$('input, textarea').bind('blur', function(e) {

       // Keyboard disappeared
       window.scrollTo(0, 1);

});

hope it helps. Michele

Michele