The problem: I'm working hard to implement a responsive UI in my app. But the keyboard IME on Android squishes my entire page layout into a frame that's about 96 pixels high when in landscape orientation. Typically this means that the input control being edited is not visible in the space above the IME. And one cannot edit a value that's not visible in Chromium. I'm assuming iOS has the same problem.
Setting a minimum height for the page helps. But the Chromium scroll-into-view implementation is not robust enough to keep up with some of the more complex page rewrites that are triggered by a change in window size in my app.
Ideally, I'd like to run the keyboard IME in "extract" mode, where the page is entirely hidden, and only the value being edited is displayed in the space above the IME. But as far as I can tell, there's no way to do that, even in Android native apps. Chromium never runs the keyboard IME in "extract" mode, even in landscape orientation.
The solution I'm current implementing: simulate "extract" IME mode by perform editing of values in a full-screen dialog that contains nothing but a single dedicated <input>.
The question is: how should I detect when to use this solution. it's easy enough to check the browser's navigator.userAgent. The Mozilla foundation recommends checking for /Mobi|Android/ (although I've seen solutions that have 40 or 50 patterns). But I'm wondering whether there's a feature-driven way to check for this instead -- something more along the lines of if ("geolocation" in navigator) ....
But as far as I can tell, there are no features related to whether and how a keyboard IME will change the layout of a page. If there are, I'd like to know. The "feature" I'm looking for is something along the lines of "Will this browser lay out my entire page in a frame that's 96 pixels high (in landscape) whenever an input control gets focus". But "does this browser uses a keyboard IME" would be satisfactory.
Any ideas appreciated.
Related
We are working on a webpage that is currently having issues with split screen resizing.
When we change the orientation of the page on a mobile browser or do a window resize on a desktop browser, we are able to run the required updates fine because we listen to the resize and orientationchange events that get fired with either type of event.
However, we just realized that with split screen on Android (and possibly split screen on iOS tablets), we aren't triggering any resize events for the window and therefore can't do proper updating of our elements based on the split screen being activated or updated (when the user moves the split).
Is this something we can work around or am I just completely missing some functionality that I should be using?
I have looked around online and haven't found anything related so far that I could use from our JS.
Thanks! Any pointers would be greatly appreciated.
Information about Multi-Window Feature in Android - doesn't go over any possible ways to detect it from a web view though, but looks at it from an Android app dev perspective
What is the most reliable way to detect if a user has a physical keyboard?
An idea is that since there is no physical keyboard window.onkeydown could be undefined (instead of null). But because of the virtual keyboard I'd suppose it to not be the case. I didn't test though.
My goal is to have input[type='number'] of an Online Timer to be replaced with wheel pickers if the user doesn't have a keyboard.
This gets really tricky with devices like the Microsoft Surface, which come with a keyboard, mouse, and have a touch screen. And you may mix all 3 input modes at any given time, or add another input method like a stylus.
Microsoft is taking the approach of abstracting input events as "pointer events". This model has been submitted to the W3C. This should give you an idea of the trend in managing input.
Still, I find it's handy to see if touch is available and operate under the assumption that—if it is—the user will use touch input at least some of the time. This can lead to design decisions to eliminate things which are completely touch-unfriendly even though that may mean compromising on mouse/keyboard functionality.
In your specific case, I would take a hard look at whether or not you even need to replace input[type=number] with a custom control. Most touch devices are reasonably modern, and many have custom, touch-friendly versions of the standard HTML inputs.
Also keep in mind accessibility scenarios which native controls probably support well "out of the box".
If you decide to implement a custom control, then I would advise detecting touch features and showing your custom control whether or not other input mechanisms are present. This means ensuring that the custom control is (at minimum) touch/keyboard/mouse friendly.
Here's my current touch test (with the disclaimer that it could break tomorrow and certainly hasn't been tested on every device):
var supportsTouch = ("ontouchstart" in window) || window.navigator.msMaxTouchPoints > 0;
I see two approaches.
The first approach would be to listen to every mouse and keyboard events. A user having a mouse is likely to also have a keyboard. A user going to a website is likely to move the mouse.
The second approach is to check the User Agent to read what Operating System is running and assume that the Android and iOS devices don't posses any keyboard. For Windows 8 I don't see how the User Agent could help, since windows 8 runs on both tablets and desktops/notebooks.
I'd rather have a more elegant solution though.
it's more reliable to detect a touchscreen and show the special widget then; just make sure the keyboard is still usable with your fancy widget for accessibility's sake.
You might be able determine the keyboard type by checking the operating system or even the screen dimensions. Android, iOS, and all devices with small screens tend not to have physical keyboards.
I'd like to detect in some "nice" way (Modernizr most likely, but whatever) whether a layout should have embedded scrollable regions of the page, or else (for some mobile use) should just flow all content as one scrollable mass.
The specific case is a "EULA"-like page, where there's a form with an "I ACCEPT" button or whatever, and then a mass of hideous all-caps legal stuff. On a big screen I'd like the whole form visible, so I'd like to put the legal stuff in its own scrolling box. However, on a mobile device that would be kind-of ugly (though I'm no mobile ux expert), so I was thinking of just dropping it all in-line so that the user could read the text (LOL) with simple swipes to scroll, and then at the bottom the buttons would scroll into view.
I suppose I could just check for touch with Modernizr, but that doesn't seem quite right.
edit — though I'm pretty sure that what I described would probably be a usability win anyway, the thing is I'm finding that my Android devices won't pay any attention to "overflow: auto" on a <div> in the middle of a page.
The approach I've taken is to rely on Modernizr.touch and Modernizr.overflowscrolling tests. If Modernizr inserts the touch and no-overflowscrolling classes in the html element in the DOM (or just check Modernizr.touch and Modernizr.overflowscrolling directly), then I avoid overflow:auto. This means that Android devices that mishandle overflow:auto do not get it.
This might be an imperfect solution; there might be devices that can handle overflow:auto that don't get it in this case. But that's not exactly the end of the world, at least in my case. And it seems to work correctly for all the most common devices/browsers.
And it has the virtue of being simple. I already had Modernizr loaded for other uses.
As others have said, the Modernizr.overflowscrolling checks for the overflow-scrolling css property, not for whether the device can scroll content within a div using overflow: auto.
In fact, in my recent testing, the Nexus 5 actually returns Modernizr.overflowscrolling as false, so it cannot be relied on.
This very small script (with no dependencies) seems to enable touch scrolling for devices (Android 2.3) lacking support...
http://chris-barr.com/2010/05/scrolling_a_overflowauto_element_on_a_touch_screen_device/
Link to repo:
https://github.com/chrismbarr/TouchScroll
I have a full-screen game in HTML+JavaScript, which uses the arrow keys as primary controls. This cannot be used on keyboardless Android devices (I haven't tested on iOS), and even if the soft keyboard had arrow keys it would take up unnecessary space. Therefore, I have added onscreen control buttons. However, the buttons are unnecessary (and absurdly large) on desktop browsers, so I would like them to not pop up unless they are needed.
What heuristics can I use to decide whether they are needed — that is, whether it is impossible or awkward for the user to input arrow-key events — other than recognizing specific User-Agents (which is straightforward, but not future-proof)?
I will of course allow the user to hide/show the buttons; I am looking for useful heuristics for choosing the default setting.
No need for any user-agent sniffing, config options or any kind of guessing. Just do this:
Have a title screen which says "press to continue".
On click or key press, hide touch controls and start game.
On touch, show touch controls and start game.
You never even needed to mention the option to the user and you auto-detected their preferred control perfectly.
Use feature detection with Modernizr: http://www.modernizr.com/docs/#touch
While this is not a reliable way to check if the user has a keyboard it is definitely reliable to see if the browser is capable of touch.
Instead of trying to guess, make it a config option for the user to choose.
If you have only arrows (left/right/up/down) you might consider adding touch-events inside the game field? This would not take up space obviously as it is layered on top of the game, so it could be 'always on'.
A computer user would not even know it is there, though he/she could use them to play your game with a mouse I guess.
The touch-device user on the other hand can much more easily use the "areas" (mid top, mid left, mid bottom and mid right for instance) because of .. well.. touching instead of using a mouse.
This might need some explaining, as you probably would not want the points to be visible to the user, but it feels like a valid option.
Even if you have 4 buttons and a 'fire', you could do this, for instance by adding a 'middle' section.
look for touch specific events such as touchstart or gesturestart and show the onscreen controls if detected.
http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html
I am not sure if the system-info api has been implemented by any browsers:
http://www.w3.org/TR/system-info-api/
rather than displaying the on-screen keyboard by default, add a button to toggle the display of the on-screen keyboard.
It might also be prudent to give the on-screen keyboard the ability to be resized.
Edit to answer question:
Keyboard should be hidden by default if most of your users are going to be on a computer,
Visible by default if most of your users are going to be on a mobile device.
You can consider checking the display size. If the display size is smaller than a certain size, you can assume that it is a mobile device and can display the Arrow Buttons. Other wise use keyboard buttons.
You can also keep an option so that user can set this manually if needed.
You could use javascript to find out the height of the windows view port and then us an if statement saying:
if ($(window).height() <= "960")) {
//Your code to display keyboard controls
//P.S. 960 is height of iPhone 4+ screen
}
Edit: Left out ) at end of $(window).height() <= "960"
it it possible to resize the browser window width to fit 2 monitors through JavaScript ?
Let's say we have 2 monitors with same resolutions : 1280x760.
is it possible to expand the width of the browser to fit 2 monitor? that 1280 X 1280.
thanks.
Firstly: Don't do this! Your users will hate you for it.
Secondly, there are a number of possible configurations possible for users who have more than one monitor.
Some users will have them set to be treated as a single extra-large display; others will have them working more independantly of each other. A colleague of mine has a display-splitter hardware which means that although he has two monitors, the PC only sees one, so when he maximizes his windows, they cover both screens. My set up on the other hand is different; when I maximize, the window expands to fill a single monitor.
Some users will even have different monitor sizes and different resolutions betweeen their monitors. I know one person who has one monitor in landscape mode, and the other rotated 90 degrees in portrait mode.
A lot of these things will make it phyically impossible to have a window that is maximized across all monitors, so even if you could make it work for some users, it wouldn't work for everyone.
Assuming you do manage to get the browser window stretched across both monitors, you now have the problem of working out how to layout your page without your text and graphics being split by the edges of the monitors. Your browser won't know where the monitor edges are, so you could easily end up with important parts of your page content being broken in half which could make your site virtually unreadable.
Even if you know in advance exactly what the user's screen resolution is going to be, you still have this problem because you don't know what the user's browser window looks like. They may have the history or bookmarks side-panels open. Their desktop settings may be different too; they may have their Windows taskbar aligned on the side of the screen rather than the bottom. None of these things are in your control, and will affect the screen space available to your browser, which in turn means you can't predict where the edges of the monitors will be even in an environment where you know the screen resolution.
In short, I don't believe it's possible, and I don't believe it's desirable. I strongly recommend not doing it.
To quote from David Flanagan, "Javascript, The Definitive Guide" (5th edition), Section 14.4.3:
"The Window object defines methods that move and resize a window. Using these methods is typically considered very poor form: the user should have exclusive control of the size and position of all windows on her desktop. Modern browsers typically have an option to prevent JavaScript from moving and resizing windows, and you shuld expect this option to be on in a sizable percentage of browsers" (emphasis added)