Today, when developing a mobile H5 page, I encountered the problem that the interface cannot return to its original position when the keyboard is retracted on IOS. The problems and symptoms are described in detail below:
Page structureThe page in question is a form structure. That is, it is similar to a structure with four input forms under a div for users to fill in mailing information. similar:
<div> <input type=text placeholder=Please fill in the province, city and county/> <input type=text placeholder=Please fill in the address/> <input type=text placeholder=Please fill in the name/> <input type=text placeholder=Please fill in the address/ Contact number/></div>
The screenshot is as follows:
The page automatically moves up when the keyboard is brought upWhen the user enters the contact number on the mobile phone, the iPhone keyboard will pop up. At this time, in order to allow the user to see the phone input box, the entire page will be moved upward on the iPhone (otherwise the keyboard will cover the phone input box). At this time, the top of the page is actually part of the distance away from our viewport (we see a row of input boxes disappearing from the interface).
The page cannot be restored to its original position when the keyboard is closedHowever, when the user completes the input and closes the keyboard, although the keyboard is put away, the page position will not be restored.
Problem analysisIn fact, this is caused by iOS's inability to prevent the part of the page from scrolling out of the viewport from falling when the keyboard is retracted. At this time, the user can drag the page back with his finger.
But the experience was not good after all.
To solve this problem, we can call window.scrollTo(0, 0)
when the user cursor leaves the input box to scroll the page to align with the top of the viewport, thereby achieving the page home effect.
So now the problem is to add blur events to all four input boxes in the form, and then call window.scrollTo
in the handler. However, whether it is added through Vue's @blur
or through DOM operations, 4 event listeners must be added, which is not very elegant. Naturally, we thought of using event proxies.
That is, we put the event listener on the top element; then define an inputBlur function to wait for triggering.
<div @blur=inputBlur> <input type=text placeholder=Please fill in the province, city and county/> <input type=text placeholder=Please fill in the address/> <input type=text placeholder=Please fill in the name/> <input type=text placeholder=Please fill in your contact number/></div>
As a result, we found that our event listener failed to fire. The reason is that the blur
event of the input box cannot bubble.
After querying, it was found that the two DOM events focus
and blur
cannot bubble in the specification. Similar to this, there are two other events focusin
and focusout
that can bubble.
Some articles on the Internet mentioned that focusin
and focusout
are DOM events supported only by IE browsers. In fact, when we look at the MDN document, we find that these two events have become a standard in the DOM 3 specification, and are supported by a large number of browsers.
Therefore, to resolve the problem decisively through these two events, we changed it focusout
<div @focusout=inputBlur> <input type=text placeholder=Please fill in the province, city and county/> <input type=text placeholder=Please fill in the address/> <input type=text placeholder=Please fill in the name/> <input type=text placeholder=Please fill in your contact number/></div>
Then, implement our event handler:
inputBlur(e) { // First, determine whether the target element that triggers the event is an input input box. We only focus on the behavior of the input box. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { window.scrollTo(0,0); } },
At this time, our problem is solved. When entering content from the input box and then clicking Finish on the keyboard to close the keyboard, the effect is in line with our expectations.
However, after testing on mobile phones, we found that when we switch directly from 电话输入框
to 姓名输入框
, the page will jitter. Let's continue the analysis.
In fact, the reason why the two input boxes jitter when switching is also very simple. Because when we switch between the above two input boxes, the page will first trigger blur
event of 电话输入框
, and then trigger focus
event of 姓名输入框
. In this case, when blur occurs, our window.scrollTo(0,0)
will be triggered, causing the page to scroll down, and then 姓名输入框
will be focused, so the keyboard will continue to pop up---this will cause the page to move upward again.
In fact, when switching between two input boxes, we do not need to trigger the window.scrollTo
behavior when the first input box is blurred. So let’s modify our code so that when the input box switching operation occurs, the behavior of the first input box can be cut off. Here we use setTimeout to solve:
<div @focusout=inputBlur @focusin=inputFocus> <input type=text placeholder=Please fill in the province, city and county/> <input type=text placeholder=Please fill in the address/> <input type=text placeholder=Please fill in the name/> < input type=text placeholder=Please fill in your contact number/></div>
inputBlur(e) { // First, determine whether the target element that triggers the event is an input box. We only focus on the behavior of the input box. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { // The input box loses focus, and the IOS keyboard needs to be pushed out of the scrolling part of the page to restore it. Scroll the page to the top of the window and align it console.log('set timer') this.timer = setTimeout(() => { console.log('timer trigger') window.scrollTo(0,0); }, 0) } }, inputFocus(e) { // If focus, remove the timer of the previous input box if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { clearTimeout(this.timer); } }
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.