H5 page development guide on mobile terminal

H5 page development guide on mobile terminal

Preface

In the usual H5 mobile development, we will inevitably encounter a variety of pitfalls. This article will take you to see how to solve it. The article is longer and it is recommended to collect it for later reference!

High energy ahead!

Video compatibility related In Android, directly using native video will cause full-screen playback, covering all elements, so use the x5 player. However, the x5 player still has problems. Although it will not cover the elements, it will add special effects by itself (covering a layer of navigation bar mask).

<video
  id='live-player'
  controls={false}
  preload="auto"
  playsInline
  mtt-playsinline= true 
  webkit-playsinline='true'
  x5-video-player-type='h5'
  x5-video-orientation='portrait'
  x5-playsinline='true'
/>
 

In this way, the x5 player can be used under Android, and the playsInline and webkit-playsinline attributes can enable inline playback under the iOS environment. However, setting the inline playback compatibility through properties is not very good, so at this time we need to use the iphone-inline-video library, which can be done by enableInlineVideo(video).

Canvas is blurred on retina screen

Just need to scale the brush according to the pixel ratio

run(canvasEl) {
    const canvas = canvasEl;
    const ctx = canvas.getContext('2d');
    const devicePixelRatio = window.devicePixelRatio || 1;
    const backingStorePixelRatio = ctx.webkitBackingStorePixelRatio ||
    ctx.mozBackingStorePixelRatio ||
    ctx.msBackingStorePixelRatio ||
    ctx.oBackingStorePixelRatio ||
    ctx.backingStorePixelRatio || 1;

    const ratio = devicePixelRatio/backingStorePixelRatio;
    if (devicePixelRatio !== backingStorePixelRatio) {
      const oldWidth = canvas.width;
      const oldHeight = canvas.height;

      canvas.width = oldWidth * ratio;
      canvas.height = oldHeight * ratio;

      canvas.style.width = `${oldWidth}px`;
      canvas.style.height = `${oldHeight}px`;
      ctx.scale(ratio, ratio);
    }
  },
 

It is clear on the PC with the same ratio of pictures, but it is blurry on the phone. What is the reason?

After research, it is found that devicePixelRatio is the cause of the problem. Because the resolution of the mobile phone is too small, if the webpage characters are displayed according to the resolution, it will be very small. Therefore, Apple only displays the 960640 resolution of the iPhone 4 on the webpage, so that devicePixelRatio=2; Android is messy, 1.5/2/3, etc., if you want the picture to be displayed more clearly on the phone, you must use a 2x background image to replace the img tag (usually 2 times), for example, the width and height of a div is 100 100 , The background image must be 200200, and then background-size: contain;, so that the displayed image is clearer; the code is as follows:

   background:url(../images/icon/all.png) no-repeat center center;
   -webkit-background-size:50px 50px;
   background-size: 50px 50px;
   display:inline-block; 
   width:100%; 
   height:50px;
 

Activate or deactivate automatic recognition of the phone number on the page;

<meta name="format-detection" content="telephone=no"> 
 

By default, the device will automatically recognize any string that may be a phone number. Set telephone=no to disable this function. The same is true for setting not to recognize emails and addresses.

h5 website input is set to type=number

Setting the type of h5 web page input to number generally causes three problems:

Problem 1: maxlength attribute is not easy to use

<input type="number" oninput="checkTextLength(this ,10)">
<script type="text/javascript">
    function checkTextLength(obj, length) {
        if(obj.value.length > length)  {
            obj.value = obj.value.substr(0, length);
        }
    }
</script>
 

Question 2: Rounding off by default when the form is submitted

<input type="number" step="0.01"/>//input type=number , step, step;number step 1, step=0.01 2 , 0.01 0.01;step min min max 
 

Question 3: Some Android phones have style problems

How to remove the default input style:

input,textarea {
    border: 0;
    -webkit-appearance: none;//, iOS , , ,iOS , border-radius 
}
 

select drop-down selection setting problem

Question 1: Right alignment implementation

Set the following properties

select option {
    direction: rtl;
}
 

Question 2: Disable the select default arrow

::-ms-expand , 

select::-ms-expand { display:none; }
 

HTML5 audio autoplay failure on mobile

Since the automatic playback of audio or video in a webpage will cause confusion or unnecessary data consumption for users, Apple and Android systems usually prohibit automatic playback and use of JS to trigger playback, which must be triggered by the user before playback; solution Idea: First trigger playback and pause by the user's touchstart (let the audio start to load), and then use JS to operate again, there is no problem; solve the code:

document.addEventListener('touchstart', function () {
    document.getElementsByTagName('audio')[0].play();
    document.getElementsByTagName('audio')[0].pause();
});
 

The CSS animation page flashes white, the animation freezes, and the picture is disordered

1. Use the synthetic properties transform and opacity to design CSS3 animations as much as possible, do not use the left and top of position to position

2. Turn on hardware acceleration

-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
 

Floating child element to prop up the height of the parent element box (BFC)

The solution is as follows:

1. The parent element is set to overflow: hidden;

2. The parent element is set to display: inline-block; etc.

The two methods here are to turn the parent element of the floating element into a BFC (block-level formatting context) element by setting the css attribute, so that the height of the child element can support the parent element; but it is best to use method 1, because the inline-block element It will bring some width and height to prop up itself

Round-trip caching problem

Clicking on the browser's fallback sometimes does not automatically execute js, especially in mobilesafari; this is related to the round-trip cache (bfcache), the solution:

window.onunload = function(){};
 

Positioned pit

The fixed positioning under IOS will be invalid when the soft keyboard is jacked up, so we use absolute instead of uniform during development.

Audio element and video element play problems in ios and andriod

<audio src="music/bg.mp3" autoplay loop controls> </audio>//, 
<audio controls="controls">//,    
    <source src="music/bg.ogg" type="audio/ogg"></source>
    <source src="music/bg.mp3" type="audio/mpeg"></source>//bg.ogg, bg.mp3    
</audio>
 

You can generally play music here. If it still doesn t work, it s probably a limitation of WeChat.

Question 3: Limitations of WeChat

If it is a limitation of WeChat, you need to call the WeChat interface at this time, and the page first introduces:

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
 

Then JS writes the WeChat event:

document.addEventListener("WeixinJSBridgeReady", function() {
    document.getElementById('music').play();
}, false);
 

summary:

1. The autoplay attribute of the audio element cannot be used on IOS and Android, and it is normal on the PC side

2. When the audio element does not have controls set, it will occupy space on IOS and Android, but Chrome will not occupy any space on the PC side.

Question 4: Safari browser automatically plays

document.addEventListener('touchstart', function(){   
    audio.play();
}, false);
 

The ios system does not support the animation pause style (animation-play-state)

H5 pages generally have BGM, and a rotating music icon is also provided for users to turn on and off the music; we hope that when the user clicks the music button, the icon will stop rotating, and then click the icon to continue running the animation along the previously stopped position; animation-play- State is the easiest way, but ios does not support

The current solution is: the music icon is responsible for running the animation, and the icon parent element is responsible for recording the rotation value when it stops.

ios prevent long-press page elements from being selected

Solution: Adding styles can prohibit users from copying, and both ios and general Android can be solved

-webkit-touch-callout:none; //; 
-webkit-user-select:none;//webkit   
-khtml-user-select:none;// 
-moz-user-select:none;// 
-ms-user-select:none;//IE10 
user-select:none; 
 

After adding this code, there will be problems on IOS. At this time, it is found that the input box cannot be inputting content; the reason for this is -webkit-user-select: none; this attribute, the solution is to set it in the css file at the same time The attributes of input are as follows:

input {      
     -webkit-user-select:auto;//webkit     
}
 

How to solve the lag/slowness when html5 encounters the scroll bar up and down

First of all, you may add height: 100% to the html and body of the page, and then it may cause the page sliding problem on IOS.

The solution is: 1. Make html and body fixed at 100% (or 100vh), 2. Then put a height: 100% div inside, set overflow-y: auto; and -webkit-overflow-scrolling: touch;

overflow-x:auto has compatibility issues in iOS, the solution:

.scroll-box {
  /*  div ,  */
  height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overflow-scrolling: touch;
}
 

How to remove the background or border generated by clicking on the element

a,button,input,textarea{ -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-user-modify:read-write-plaintext-only;//-webkit-user- A side effect of modify is that the input method can no longer input multiple characters} or a,button,input,textarea{ -webkit-tap-highlight-color: rgba(0,0,0,0);}

The browser backs up without refreshing

This situation has been encountered before, and I will talk about it here; it will mainly happen in the webview a little bit more, when the page is clicked back, the page appears in cached form, not after refreshing, in many cases this is not the effect you expected, solve it The method is to use js:

 1 
window.addEventListener('pageshow', () => {
  if (e.persisted || (window.performance && 
    window.performance.navigation.type == 2)) {
    location.reload()
  }
}, false);

 2:
window.history.replaceState(null, '', window.location.href + '?timestamp=' + new Date().getTime());

 

onpageshow is triggered every time the page is loaded, whether it is loaded from the cache or loaded normally, this is the difference between it and onload; persisted judges whether the page is read from the cache

When the page is accessed through history and forward and backward. type value is 2

transition clear splash screen

-webkit-transform-style: preserve-3d;// 3D  3D
-webkit-backface-visibility:hidden;//
-webkit-perspective: 1000;
 

Solve the invalidity of the active pseudo-class

<body ontouchstart></body>
 

Top status bar background color

apple-mobile-web-app-capable Web ; :
<meta name="apple-mobile-web-app-capable" content="yes">//content yesWeb 
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
 

Note: Unless you use apple-mobile-web-app-capable to specify the full-screen mode first, this meta tag will not have any effect; if the content is set to default, the status bar is displayed normally; if it is set to blank, the status bar will be There is a black background; if set to blank-translucent, the status bar is displayed as black translucent; if set to default or blank, the page is displayed below the status bar, that is, the status bar occupies the upper part; the page occupies the lower part, The two do not block each other or are blocked; if set to blank-translucent, the page will fill the screen, and the top of the page will be covered by the status bar (it will cover the height of the page 20px, while the Retina screen of iphone4 and itouch4 is 40px); default The value is default.

ios area

Safari 3D transform will ignore the z-index level

Under the Safari browser (this Safari browser includes Safari on iOS, WeChat browser on iPhone, and Safari browser on Mac OS X), when we use 3D transform, if the ancestor element does not have overflow:hidden/Limitations such as scroll/auto will directly ignore the z-index stacking order settings of itself and other elements, and directly use the real-world 3D perspective for rendering. For example, in the following scene, the module in the red box in the figure uses 3D transform to perform rotation animation, but in the Safari browser, the z-index of the two-dimensional code mask layer is ignored, and the real-world 3D perspective is used as a result Perform rendering. There are overlapping bugs:

Solution:

Parent, any parent, non-body level, set overflow: hidden to restore the same rendering as other browsers. Fight poison with poison. Sometimes, the page is complex, we can not set overflow: hidden for the parent, then you can set a large enough translateZ value for the affected element, such as translateZ(100px).

White screen when ios input

This problem seems to be only in ios9

Solution: Just add relative positioning to the parent element of the input, which is very magical

The problem of poor support for input keyboard events such as keyup/keydown/keypress in IOS

After investigation, it was found that the IOS input method (whether it is a third party or its own) can detect English or numeric keyups, but cannot detect Chinese keyups. After entering Chinese, you need to click the back button to start the search; the solution is Use html5's oninput event to replace keyup, and achieve a keyup-like effect through the following code;

1. Modified the selection status of input:checkbox or input:radio element, checked attribute changed

2. The value of the input: text or textarea element is modified, and the value attribute changes

3. The selected item of the select element is modified, and the selectedIndex property changes and the input monitor is used uniformly

<input type="text" id="testInput">
<script type="text/javascript">
    document.getElementById('testInput').addEventListener('input', function(e){
        var value = e.target.value;//e.target ; , , e.target , e.target this 
    });
</script>
 

IOS keyboard letter input, the default first letter capitalized solution

Set the following properties

<input autocapitalize="off" autocorrect="off"/>
 

//The three attributes of input autocomplete: the default is on, which means whether to let the browser automatically record the input value. You can add autocomplete="off" to the input to close the record and keep the input content confidential; autocapitalize: automatic capitalization; autocorrect: Error correction

About the optimization of fonts on iOS and OS X (the horizontal and vertical screens will appear inconsistent in bold fonts, etc.)

The iOS browser will reset the font size when the screen is horizontal. Setting text-size-adjust to none can solve the problem on iOS, but the font scaling function of the desktop version of Safari will fail, so the best solution is to set text-size-adjust to 100%

-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
text-size-adjust: 100%;
 

In some cases, non-clickable elements such as (label, span) listen to the click event and will not trigger under ios

In this case, you only need to add a line of css code to the element that does not trigger the click event.

cursor: pointer;
 

ios support for time date() is not the same

var date =new Date("2019/10/21"); 
 

Debugging found that 2019/10/21 is equivalent to 2019-10-21 00:00:00, which means that ios starts from 0 by default, and we don't need to set the following hours, minutes and seconds to 00:00:00

iOS (safari) tag binding click event is invalid

iOS (safari) sometimes a label binding click event is invalid, just add an empty onclick="", such as:<a onclick=""></a>

The location.href jump page is blank in ios

SetTimeout on the first layer of location.href will solve it!

setTimeout(() => {
       window.location.href = 'www.juejin.im'
}, 0);
 

The bug solution when the keyboard bounces and falls

Click to view

summary

The road is long and long, and drifting further on the compatible road