preface

Once I saw someone sharing a similar article when browsing nuggets article, the general idea is to use 6 input to achieve 6 input boxes, by adjusting the input style to achieve this input SMS verification code function. As it happens, there is a recent project to implement such captchas. Left left left



According to the ideas I learned from similar technical articles before, I also adopted 6 input to realize it. PC simulation performed well in the development environment, meeting expectations, and self-test performed well with Android phones, without finding any problems. You then deploy to the test environment and commit the tests.

The problem


Sure enough, this implementation fails on IOS 😱, as shown below



You can see that the whole page shakes during the process of entering the SMS verification code, which makes the user experience very unfriendly. 😰 this effect is completely dare not put into the online, that there is a problem to try to solve the problem, analysis of IOS and Android on the different performance, trace the root to find the crux.

Keyboard pop-ups in different ways

  • IOS: the IOS keyboard is at the top of the window, when the keyboard is up, the height of the WebView does not change, but the scrollTop changes, and the page can scroll. The maximum scrolling value of a page is the height of the keyboard that pops up. If the page happens to scroll to the bottom when the keyboard pops up, the scrollTop change value is the height of the keyboard, and in other cases, it cannot be obtained. This makes it difficult to get the true height of the keyboard on IOS.
  • Android: WebView space, the space is less than or equal to the keyboard space, the height difference will change with the layout and different, some thinkKeyboard height + page height = original page height; Is a false and misleading formula that can only be applied in the case of a very coincidental layout.

Different manifestations of keyboard folding

  • IOS:Trigger buttons on the keyboard to collapse the keyboard or page area outside the input box, the input box will lose focus, so the blur event of the input box will be triggered.
  • Android: When the button on the keyboard is triggered, the input box does not lose focus, so it does not trigger the blur event on the page. When a region outside the input box is triggered, the input box loses focus, triggering the blur event of the input box.

Conclusion reason

Considering the different performance of keyboard popup and keyboard popup on different platforms, we can see the problem: on IOS, when a number is entered between six inputs, the focus of the previous input will be lost immediately, and the focus of the next input will be immediately again, resulting in page jitter.

solution


Since page jitter is caused by frequently getting focus and losing focus between multiple inputs, why not just use one input? Concrete ideas are analog input box with six div tags below small horizontal line, then use to build an input on the first horizontal, each input a digital input current input box moves to the right, and set the current input box always empty (this does not prevent access to input Numbers), keep the flashing cursor, to show the numerical input on an analog input box before, When the focus is lost after the input of 6 digits, the keyboard is folded up, input is hidden, and the page starts loading, and the interface verification verification code is adjusted. If the verification fails, the input is displayed and the original input status value is cleared to restore to the initial state. TSX bound mobile phone number and amount are all obtained from the interface. For convenience of display, pseudo-data is used here. If a VW or REM layout is used, the corresponding offset units need to be converted.

<div className={styles.captchabody}> <div className={styles.amount}>¥10000</div> <div className={styles.phone}> <p ClassName ={styles.tip}> Enter the SMS verification code </p> <p className={styles.send}> < SPAN > The verification code has been sent to </ SPAN > < SPAN className={styles.number}>137****5064</span> </p> </div> <div className={styles.phoneCode}>{renderCaptchaItem()}</div> <input value={''} ref={inputEle} style={{ transform: `translate(${x}px, -32px)` }} className={styles.inputItem} autoFocus onChange={handleChange} onKeyDown={handleDelete} maxLength={1} /> </div> <div className={styles.reGet + ' ' + (count > 0 ? ": styles.hide)}> {count} after seconds retrieve </div>Copy the code

Less style and specific function interaction details I will not post code, interested can refer to my GitHub, I have sorted it out

The resources


  • H5 keyboard compatibility summary