I have been working on an H5 chat project recently, and I have encountered one of the biggest pitfalls: the input box gets focus, the soft keyboard pops up, and the input box is required to be adsorbed (or pushed) on the input method box. The requirements are very clear and seem simple, but actually they are not. After experimenting with some models, we found that there are mainly the following problems:
Let’s explore the solutions to the above-mentioned problems one by one.
Get the pop-up and retract status of the soft keyboardIt is important to know whether the soft keyboard is up or down, and subsequent compatibility processing must be based on this. However, H5 does not directly monitor the native events of the soft keyboard. It can only indirectly monitor the performance of other aspects of the page by popping up or retracting the soft keyboard, saving the country. Moreover, the performance on IOS and Android is different.
IOS soft keyboard pop-up performanceOn iOS, when the input box (input, textarea or rich text) gets the focus, the keyboard pops up, the page (webview) is not compressed, or the height (height) does not change, but the page (webview) as a whole scrolls up. And the maximum scroll height (scrollTop) is the soft keyboard height.
Android soft keyboard pop-up performanceSimilarly, on Android, the input box gets focus and the keyboard pops up, but the height of the page (webview) will change. Generally speaking, the height is the height of the visual area (original height minus the height of the soft keyboard), except because the page content is Expanding can produce scrolling, but the webview itself cannot scroll.
IOS soft keyboard collapse performanceWhen the retract button on the soft keyboard or the page area outside the input box is triggered, the input box loses focus and the soft keyboard retracts.
Android soft keyboard collapse performanceWhen an area outside the input box is triggered, the input box loses focus and the soft keyboard is retracted. However, when the retract button on the keyboard is triggered, the input box will not lose focus, and the soft keyboard will also be retracted.
Monitor the pop-up and collapse of the soft keyboardBased on the above different performances of keyboard pop-up and collapse on IOS and Android, we can perform the following processing separately to monitor the pop-up and collapse of the soft keyboard:
// Judge the device type var judgeDeviceType = function () { var ua = window.navigator.userAgent.toLocaleLowerCase(); var isIOS = /iphone|ipad|ipod/.test(ua); var isAndroid = /android/.test( ua); return { isIOS: isIOS, isAndroid: isAndroid }}()// Listen to the soft keyboard pop-up and collapse events function of the input box listenKeybord($input) { if (judgeDeviceType.isIOS) { // IOS keyboard pops up: IOS and Android input boxes get focus and the keyboard pops up $input.addEventListener('focus', function () { console.log('IOS keyboard It pops up! '); // Operation after the IOS keyboard pops up}, false) // IOS keyboard retracts: IOS If you click outside the input box or click the retract button, the input box will lose focus and the keyboard will retract. $input.addEventListener('blur', () => { console.log('IOS keyboard retracted!'); // Operation after IOS keyboard is folded }) } // Andriod keyboard is folded: When the Andriod keyboard pops up or folds, the page height will change, and based on this, the keyboard is folded if (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight || document.body.clientHeight; window.addEventListener('resize', function () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < resizeHeight) { console.log('Android keyboard is put away!'); // Operation after Android keyboard is put away} else { console.log('Android keyboard pops up! '); // Operation after Android keyboard pops up} originHeight = resizeHeight; }, false) }}var $inputs = document.querySelectorAll('.input');for (var i = 0; i < $inputs.length; i++) { listenKeybord($inputs[i]);}When popping up the soft keyboard, the input box always scrolls to the visible area.
Sometimes we will make an input form with many input items. The input box gets the focus and the soft keyboard pops up. When the input box is located at the lower part of the page, on IOS, the entire webview will be rolled up a certain distance so that the focused input box is automatically in the visible area. However, this will not be the case on Android. It will only change the height of the page. , without scrolling to the currently focused element into the visible area.
Since the above has been implemented to monitor the pop-up and retract of the IOS and Android keyboards, here, you only need to scroll (scrollIntoView()) the focus element to the visual area after the Android keyboard pops up. To see the effect, you can click here.
// Get the focus element and scroll to the visible area function activeElementScrollIntoView(activeElement, delay) { var editable = activeElement.getAttribute('contenteditable') // The input box, textarea or rich text does not scroll to the visible area after getting the focus area if (activeElement.tagName == 'INPUT' || activeElement.tagName == 'TEXTAREA' || editable === '' || editable) { setTimeout(function () { activeElement.scrollIntoView(); }, delay) }}// ...// Operate activeElementScrollIntoView($input, 1000);// ... after the Android keyboard pops upEvoke a pure numeric soft keyboard
The above form input box requires you to enter a phone number. Similar to this, a numeric soft keyboard will pop up. Since we talk about soft keyboard compatibility, let’s insert it here. A better solution is as follows:
<p>Please enter your mobile phone number</p><input type=tel novalidate=novalidate pattern=[0-9]* class=input>
If you use IOS12 and V6.7.4+ version of WeChat browser to open the above form input demo, you will be surprised to find that after the keyboard is retracted, the page that was originally scrolled up does not return to the bottom position, causing the original keyboard to bounce. The starting position is empty.
In fact, this is an Apple bug in iOS and will appear on all IOS12 devices packaged with Xcode10. WeChat has officially given a solution. Just scroll the page (webview) back to the bottom position of the window (clientHeight position) after the soft keyboard is closed. The repaired above form input demo can be clicked here
console.log('IOS keyboard is put away!');// WeChat browser version 6.7.4+IOS12 will show that after the keyboard is put away, the view is pushed up but not down var wechatInfo = window.navigator.userAgent.match( /MicroMessenger//([/d/.]+)/i);if (!wechatInfo) return;var wechatVersion = wechatInfo[1];var version = (navigator.appVersion).match(/OS (/d+)_(/d+)_?(/d+)?/);if (+wechatVersion.replace(//./g, '') >= 674 && +version[1] >= 12) { window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));}Compatible with third-party input methods
Having said so much above, in fact, more than half of the pitfalls of the H5 chat input box have been filled. Next, let’s take a look at the basic HTML structure of the chat input box.
<div class=chat__content> <div> <p>Some chat content 1</p> </div> <!--Omit thousands of lines of chat content--></div><div class=input__content> <div class =input contenteditable=true></div> <button>Send</button></div>
style
/* Omit some styles */.chat__content { height: calc(100% - 40px); margin-bottom: 40px; overflow-y: auto; overflow-x: hidden;}.input__content { display: flex; height: 40px; position: absolute; left: 0; right: 0; bottom: 0; align-items: center;}/* Omit some styles*/
It's very simple, just divide the content area and input area. The input area is absolutely positioned. According to the above form input demo method, it is true that most Android browsers are fine, but the test was on IOS. UC Browser cooperates with the native input method and For third-party input methods (such as Sogou input method), the input box will be completely blocked; for QQ browser or WeChat browser, with a third-party input method, the input box will be half blocked; with Baidu browser, with a third-party input method, the input box will be blocked It will also be completely covered. To view the effect, you can visit here in the corresponding browser.
On UC Browser, after the soft keyboard pops up, the height of the title bar above the browser has a delay dynamic effect of decreasing in height, which causes the webview to scroll down a bit and the bottom input box to scroll to the non-visible area.
As for the third-party input method, it is speculated that the initial scroll positioning of the webview is incorrect due to an incorrect height calculation after the input method panel pops up. In fact, these two points are caused by the webview not scrolling in place. After the soft keyboard pops up, the focus element can be scrolled to the visible area again, forcing the webview to roll into place.
console.log('Android keyboard pops up!');activeElementScrollIntoView($input, 1000);Hack solution compatible with Android Xiaomi browser
On Android's Xiaomi browser, after applying the above solution, I found that the chat input box was still tightly blocked, and scrollIntoView() still remained motionless. So I guess it's actually because the soft keyboard has been scrolled to the bottom, and the page height is greater than the height of the visual area when the soft keyboard pops up. In this way, the page height can only be forcibly increased after the soft keyboard pops up so that the input box can be displayed. Based on the above, it is compatible with third-party input methods. To view the effect, you can click here.
// Andriod keyboard retracts: The height of the page will change when the Andriod keyboard pops up or retracts. Based on this, the keyboard retract is known if (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight || document.body.clientHeight ; window.addEventListener('resize', function () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < resizeHeight) { console.log('Android keyboard is closed!'); // Fix the problem that the input box is still blocked by the input method in Xiaomi browser if (judgeDeviceType.isMiuiBrowser) { document.body.style.marginBottom = '0px'; } } else { console.log('Android keyboard pops up!'); // Fix the problem that the input box is still blocked by the input method in Xiaomi browser if (judgeDeviceType.isMiuiBrowser) { document.body.style.marginBottom = '40px'; } activeElementScrollIntoView($input, 1000); } originHeight = resizeHeight; }, false )}Summarize
The H5 end has a long road ahead with many pitfalls and requires constant attempts. It is a prerequisite to understand the performance difference between the soft keyboard pop-up page on IOS and Android. The second step is to scroll the focus element to the visible area. At the same time, the differences in third-party input methods and some browsers must be taken into account.
The above is the entire content of this article. I hope it will be helpful to everyone’s study. I also hope everyone will support VeVb Wulin Network.