I recently completed an H5 project that worked perfectly in the browser emulator, but turned out to be buggy when it came to testing. Stepped on a lot of pits, so think over the pain, write an article to record these problems, to share with everyone.

1. After the soft keyboard of an IOS version is retracted, the page does not return to the original position

On older iphones, the soft keyboard pops up and moves the covered form up, but when it collapses it can’t be undone, causing the page to lose focus, especially if there are pop-up layers on the page.

This requires manual restoration of the page after the keyboard is down

const isRest = false
document.body.addEventListener("focusin", () => {// Handle the event that the soft keyboard pops up isReset =false;
});
document.body.addEventListener("focusout", () => {// Soft keyboard retract event processing isReset =true;
    setTimeout(() => {// When the focus is switched between input boxes in the pop-up layer, the focus is not returnedif(isReset) { const bfscrolltop = document.body.scrollTop; document.body.scrollTop = bfscrolltop; }}, 100); });Copy the code

2. Android cannot move the input focus out after clicking ok on the soft keyboard

The author uses blur to verify the form, but clicking the soft keyboard to confirm the form on an Android phone will not trigger blur action, which makes the user experience very bad.

In the case of Android phones, do the following:

const originalHeight = document.documentElement.clientHeight || document.body.clientHeight;
window.onresize = function() {
    var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
    if(resizeHeight - 0 >= originalHeight - 0) { document.activeElement.blur(); }};Copy the code

Note: Android phones can’t use FocusOut to listen for soft keyboard retractions, only onresize events.

3. Use REM adaptation

The team based their design on the iPhone6s, which has a 375:667 aspect ratio. They want to zoom in on other devices.

So we used REM and did not use media query to set different font sizes for different widths. Instead, they used existing wheels

    ;
    (function (designWidth, maxWidth) {
      var doc = document,
        win = window,
        docEl = doc.documentElement,
        remStyle = document.createElement("style"),
        tid;

      function refreshRem() {
        var width = docEl.getBoundingClientRect().width;
        maxWidth = maxWidth || 540;
        width > maxWidth && (width = maxWidth);
        var rem = width * 16 / designWidth;
        remStyle.innerHTML = 'html{font-size:' + rem + 'px; } ';
      }

      if (docEl.firstElementChild) {
        docEl.firstElementChild.appendChild(remStyle);
      } else {
        var wrap = doc.createElement("div"); wrap.appendChild(remStyle); doc.write(wrap.innerHTML); wrap = null; } // The wiewPort must be set before refreshRem is executed, otherwise refreshRem will be executed twice; refreshRem(); win.addEventListener("resize".function() { clearTimeout(tid); // Prevent tid = from being executed twicesetTimeout(refreshRem, 300);
      }, false);

      win.addEventListener("pageshow".function (e) {
        if(e.persisted) {// Recalculate clearTimeout(tid) when browser backs up; tid =setTimeout(refreshRem, 300); }},false);

      if (doc.readyState === "complete") {
        doc.body.style.fontSize = "16px";
      } else {
        doc.addEventListener("DOMContentLoaded".function (e) {
          doc.body.style.fontSize = "16px";
        }, false);
      }
    })(375, 750);
Copy the code

Using JS dynamic calculation, after testing this scheme is the best effect.

4. Sliding penetration problem

On the mobile end, the slide of the pop-up layer will make the page below the pop-up layer follow the scroll, which will cause a very bad effect to the user. There is a well-established solution to this problem in the community:

body-scroll-lock

It’s easy to use:

const bodyScrollLock = require('body-scroll-lock');
const disableBodyScroll = bodyScrollLock.disableBodyScroll;
const enableBodyScroll = bodyScrollLock.enableBodyScroll;

const targetElement = document.querySelector("# pop-up layer element");
if(conditions)disableBodyScroll(targetElement);
else enableBodyScroll(targetElement);
Copy the code

One of the most painful aspects of H5 development was compatibility, a process that tested developers’ experience and patience.

What is wrong with the above or better solutions, welcome to leave a message to exchange. 😄