The problem
Problem description:
In ios mobile phones, when the page contains an input box, click the input box and the keyboard will be up, which will invalidate the fixed elements in the page. Therefore, the elements of bottom suction and top suction are misplaced. This is what happens in the following video, where the top element is pushed out of view and the bottom element is pushed onto the keyboard.
The Gif format is as follows:
The UI wants to be optimized:
At first, the UI proposed three optimization points for the problems in this video:
1, hope that the top elements can continue to top
2, I hope the bottom elements can continue to suck bottom
3. You want the input field to stay 48px above the keyboard when the keyboard is up
The final optimization point:
After some research, I collected feasible methods, combined with the limited time factor, and after coordinating with the UI, the three optimization points turned into the following three optimization points. At the same time, it also refers to online articles and adds some optimization points that may occur under special circumstances.
1, the top element can continue to top
2. Bottom-sucking elements (i.e. buttons) can appear on top of the keyboard after the keyboard has popped up
3, the keyboard is up, the input box appears in the visual area. (Ios itself supports this, but Android doesn’t actively make input boxes visible.)
4. For some wechat WebViews under ios system, it was found that when the soft keyboard was put away, the scrolling page did not scroll down, resulting in a gray area in the following area.
Questions to understand first
Before addressing these issues, you need to understand the following two questions:
1. What happens when the keyboard is played
It doesn’t look the same on ios and Android. This reference to the Jurey Big guy provided this article: WebView soft keyboard compatibility solution
IOS soft keyboard play performance
On IOS, the input, textarea, or rich text gets the focus, the keyboard comes up, the webview doesn’t get compressed, or the height doesn’t change, the whole webview just rolls up, The maximum scrollTop is the height of the soft keyboard.
Android soft keyboard play performance
Similarly, on Android, the input field gets focus and the keyboard pops up, but the webView height changes. In general, the height is the height of the viewable area (the original height minus the soft keyboard height), except that the WebView itself cannot be scrolled because the page content is stretched out to produce scrolling.
IOS soft keyboard folding performance
When the keyboard or page area outside the input field is triggered, the input field loses focus and the soft keyboard collapses.
Android soft keyboard performance
When an area outside the input box is triggered, the input box loses focus and the soft keyboard collapses. However, the input field does not lose focus when the pad keyboard on the keyboard is triggered, as is the soft keyboard.
2. Why will fixed fail
Since the ios keyboard is up, the page will move, so why fixed will fail.
See this article on ios keyboard problems and the visualViewport API
One problem ios designers had in mind at the time was that when the keyboard was up, the page didn’t know it was there. Wouldn’t it be a bad experience, then, if the target you’re going to enter (the “input box”, such as input, Textarea, or the contenteditable elements in general) happens to be covered by a keyboard that pops up?
To solve this problem, ios designers let the WebView scroll, but the scrolling results were a little unexpected: The input box itself understandably scrolls to the middle of the actual viewable area, but fixed elements don’t recalculate, but stay in their relative position and are pushed up along with the input box; During scrolling, you also allow the bottom of the screen to go beyond the bottom of the page (” overscroll “) to expose the input field as much as possible. When you fold up the keyboard, the “overscrolled” section will bounce back, the fixed element will recalculate, but the page will not be in the same position as it was before you opened the keyboard.
3, how to listen to the keyboard up and down the action
Since it is the keyboard playing up caused by the problem, so the solution to this problem is necessary to listen to the keyboard up and down the action, that how to listen. Also see this article: Compatibility solutions for soft keyboards on WebView
Considering the different performance of the keyboard up and down on IOS and Android, we can do the following separately to listen for the soft keyboard up and down:
Ios
On IOS, listen for the focus event in the input box to know that the soft keyboard is up, and listen for the blur event in the input box to know that the soft keyboard is down. On Android, the listening WebView height changes, the height gets smaller and it knows that the soft keyboard is up, otherwise the soft keyboard is down.
// IOS Keyboard bounces: The IOS keyboard bounces when the input box is focusedinputRef? .current? .addEventListener('focus'.function () {
// When the IOS keyboard is up
}, false)
// IOS Keyboard collapse: When you click the area outside the input box or click the collapse button, the IOS input box will lose focus and the keyboard will collapse.inputRef? .current? .addEventListener('blur'.() = > {
// The IOS keyboard is folded up
})
Copy the code
android
On Android, listen for webView height changes, height decreases to know that the soft keyboard is up, otherwise the soft keyboard is down.
useEffect(() = > {
const { isAndroid } = Util.getOS(' ');
let originHeight = document.documentElement.clientHeight || document.body.clientHeight;
const handelAndroidResize = throttle(() = > {
const resizeHeight =
document.documentElement.clientHeight || document.body.clientHeight;
if (originHeight < resizeHeight) {
// The Android keyboard is folded up
} else {
// When the Android keyboard is up
}
originHeight = resizeHeight;
}, 300);
if (isAndroid) {
window.addEventListener('resize', handelAndroidResize, false);
}
return () = > {
if (isAndroid) {
window.removeEventListener('resize', handelAndroidResize, false); }}; } []);Copy the code
The solution
The following is the beginning of a pair of above said problems to analyze and solve:
1, the top element can continue to top
The problem is that it only happens on ios because the way ios and Android handle keyboard pop-ups is different.
At that time, I found that there was no suitable solution, but the next best thing, since H5 has no way to solve the top problem, then the ability of the client is better, the client header does not belong to webView content, naturally, when the WebView is pushed, the client header will still be in the top state.
In our case, the JSB capability on the client only supported a simple back button with a centered header. Therefore, the “historical evaluation” in the upper right corner cannot be written directly with JSB ability, so we can only discuss with UI students to change the original design scheme. With the following design, you can write headers using THE JSB capability.
Derivative questions:
But this raises a new problem: on Android apps, the bottom button is blocked.
The GIF format is as follows:
Derivative problem solutions
We didn’t have this problem when we used headers that were written by the front end, presumably because the Height of the WebView on an Android phone when the keyboard is up is shortened to the height of the entire screen minus the height of the keyboard, and in our previous implementation, because of the immersion header, So the front end WebView height is the height of the entire screen, and now since we’re using client-side JSB capabilities, the remaining webView height has to be subtracted from the height of the header header. So the solution is to make the keyboard up and add the margin-bottom button and the element at the bottom to the height of the header.
2. Bottom-sucking elements (i.e. buttons) can appear on top of the keyboard after the keyboard has popped up
As for this problem, it does not exist on Android because the WebView is narrowed. As for ios, the maximum scrolling distance in ios is the height of the keyboard, but it may not be the height of the keyboard, so the bottom suction button will be blocked.
Visible GIF as follows:
The solution:
When the keyboard is playing, add scrollIntoView(true) to the input field; Methods. This might actually only apply to my situation, but here’s how the solution works: ScrollIntoView (true) wants the top of the input box to scroll flush with the top of the viewing area, but since the maximum scrolling distance after the ios keyboard is up is equal to the height of the keyboard, using this method will make the WebView scroll distance equal to the height of the ios keyboard, achieving the effect of the suction button suction bottom.
3, the keyboard is up, the input box appears in the visual area. (Ios itself supports this, but Android doesn’t actively make input boxes visible.)
This is easy, just scroll the element into the view, just use the scrollIntoView(true) method.
4. The page should not slide down naturally when the ios soft keyboard is put away
For some wechat WebViews under ios system, it was found that when the soft keyboard was put away, the scrolling page did not scroll down, resulting in a gray area in the following area. This is actually an Apple IOS bug that appears on all Xcode10 packaged IOS12 devices. Wechat official has given the solution (click to see).
Problem: GIF
As shown in the figure:
The solution:
When the keyboard is retracted, add one of the following solutions
- Scroll to the top
window.scrollTo(0.0)
Copy the code
- Roll to the bottom
window.scrollTo(0.Math.max(document.body.clientHeight, document.documentElement.clientHeight));
Copy the code
This scenario code
const handleIosInputBlur = () = > {
// The IOS keyboard is folded up
// wechat browser version 6.7.4+IOS12 will appear after the keyboard is folded, the view is on the top is not down
const wechatInfoRe = /MicroMessenger\/([\d\.]+)/i;
const wechatInfo = wechatInfoRe.exec(window? .navigator? .userAgent);const wechatVersion = wechatInfo && wechatInfo.length > 1 && wechatInfo[1];
const osInfoRe = /OS (\d+)_(\d+)_? (\d+)? /i;
const osInfo = osInfoRe.exec(navigator.appVersion);
const osVersion = osInfo && osInfo.length > 1 && osInfo[1];
if(! wechatVersion || ! osVersion) {return;
}
const height = Math.max(document.body.clientHeight, document.documentElement.clientHeight);
if (Number(wechatVersion.replace(/\./g.' '> =))674 && Number(osVersion) >= 12) {
window.scrollTo(0, height); }};Copy the code
Final result:
Ios
The android
Reference article:
Compatible with WebView’s soft keyboard
How does jS get iOS keyboard height
Common problems and solutions of input Boxes on mobile Devices
Ios keyboard puzzle and visualViewport API
❤️ Thanks for your support
That’s all for this share. Hope it helps you
If you like it, don’t forget to share, like and collect it.
Welcome to pay attention to the public number ELab team receiving good articles ~