A preface

Recently, THE author has been developing JINGdong APP embedded H5 project and wechat small program mall project, during which I encountered a lot of pitfalls. This article is mainly aimed at the h5 | Hybrid | WeChat applet three directions to relate I met pit, as well as detailed explain how I solve the problem.

Mobile adaptation has always been a headache. If you want to understand the mobile terminal, also need a lot of practical experience, sometimes there is no problem in the PC side debugging, but there will be problems in the M side. Here are 16 questions I have come across in my work. I hope you can collect a wave in case you need it.

Like the author can “like + collect” a wave, continue to update the front-end core article.

M end H5 trampling pit summary

The following are the problems encountered by JINGdong in embedding H5 and H5 landing page. Let me show you a mind map.

1 ios: :postion:fixed Locate the screen jitter problem

background

When DEVELOPING the business page of JINGdong APP,Hybrid H5, I encountered a very difficult problem, because this page was similar to the animation effect of the product details page of JINGdong APP. The animation is shown below. Android phone is normal, but ios phone, slider shake problem, pictures will appear flashing effect. For a long time, I searched a large number of solutions on the Internet, but none of them actually solved the problem. I also tried several methods, but failed. At that time, I was overwhelmed 😭😭😭.

The whole process is that when the view container slides up, the goods card container needs to move slowly. First, the goods card needs to move out of the standard flow and set position: Fixed. Then control the top value to control the slow movement of the slider. However, in the process of container upward sliding, the slider will appear jitter, flashing effect.

🤔 This is probably the reason why ios is unfriendly to position. Similar reasons are also common in small programs.

The solution

Search online and explore your own failed solutions

① Setting height:100% for top elements (this doesn’t work).

② Add the transform: Translate (0) attribute.

③ Change the layout from fixed positioning to absolute positioning, scrollbar based on itself. (It can fundamentally solve the problem of occasional screen hopping, but then comes the problem of ios scroll bar, which can only be triggered effectively based on Document, so abandon this scheme)

(4) Without changing the layout, the fixed positioning is changed to absolute positioning. The scrollbar is based on document, and the positioning value is completely driven by data. (It can fundamentally solve the problem of occasional screen hopping, but the ensuing problem is to constantly change its top value, resulting in slow update, poor user experience and poor fluency, so give up this solution)

⑤ -webkit-overflow-scroll:touch

⑥ Background-attachment: Fixed (does not work)

The solution

After much trying, a solution came to mind. Continue to use fixed positioning, because we need to pass positioning here, jitter is not the cause of fixed positioning alone. It also has a lot to do with changing top values frequently. Instead of changing top, use Transform: translateY to move the view up and down.

<view class="scroll_box" style={{ transform:`translateY(${ top }px)` }}    >
   <! -- A lot of things -->
</view>
Copy the code
.scroll_box{
    position:fixed;
}
Copy the code

2 Android problem: border-radius: 50% fillet is stretched

background

When we expect border-radius: 50%; To draw the dots. It may not be obvious if the circle is large, but if the circle is small, it will be obvious that the circle is not round, that the circle is stretched.

The general effect is shown below.

🤔 analysis reason, in the mobile terminal is usually adapted different phones, so using rem, layout, rem in conversion of px, would be a decimal value, the android do to less than 1 px process (different browsers to less than 1 px way is different, some use rounded, show some greater than a value 1 px or give up), Resulting in rounded corners are not round; On ios, we don’t have this problem.

The solution

Transform: Scale (.5) : Transform: Scale (.5) : Transform: Scale (.5) : Transform: Scale (.5) : Scale (.5) This method works very well, and the resulting circle is very round.

Let’s take an example 🌰 :

<div class="round" ></div>
Copy the code

Did not make compatible with the previous style,

.round{
    border-radius:50%;
    width:10px;
    heigth:10px;
}
Copy the code

to

.round{
    border-radius:50%;
    width:20px;
    heigth:20px;
    transform: scale(.5);
}
Copy the code

Taro-h5 is used here, and px is automatically converted into REM.

The question

Sometimes this happens when we make the height of the element very small.

<view class='box'  /> 
Copy the code
.box{
    width:100px;
    height:1px;
}
Copy the code

Because we set the height to 1px, when taro converted to REM, it would be rounded off. The 1px element was replaced by 0px, which caused the bug that 1px elements could not be displayed. The solution is the same as the above principle. Transform scaleY(.5); transform scaleY(.5); The y direction is going to be 1/2 of what it was before.

.box{
    width:100px;
    height:2px;
    transform: scaleY(.5);
}
Copy the code

3 iOS problem: the last child element iOS bottom set margin-bottom invalid

background

This problem can easily occur on ios. When the last element of the view container is set to margin-bottom, expecting a distance from the entire container view, it is found that it is normal on Android phones, but in ios, margin-bottom will be invalid.

The solution

The solution to this problem is also very, very simple. Changing margin-bottom to padding-bottom can fundamentally solve the problem.

Example 🌰 :

<div class="box" ></div>
Copy the code
.box{
   margin-bottom: 148px;
}
Copy the code

to

.box{
   padding-bottom: 148px;
}
Copy the code

4 The ios screen goes blank

background

Hold your finger down to create a blank area at the top of the screen. Hold your finger on the screen and pull to create a blank area at the bottom. The color of the blank area will be different when opened on different app platforms. The blank background embedded in JINGdong APP H5 is white, but it is gray in wechat.

🤔 Possible cause: In iOS, the TouchMove event is triggered when a finger is dragged up or down. This event triggers the entire WebView container, which will naturally be dragged, leaving the rest blank.

The effect is as follows:

The solution

1. Smoke screen, it works

For example, for jingdong APP with a white background, if our background is also white, we can solve this problem by filling the whole container with the whole top container and positioning. So that the view doesn’t follow a pull-up or a pull-down. If the white space color matches the background color, it visually cancels out the sliding effect. Fundamentally solve the problem of gaps.

A word against the code 😜.

<div id="root" >
   <! -- A lot is omitted here -->
</div>
Copy the code
#root{
    position: fixed;
    left:0;
    top:0;
    bottom: 0;
    right: 0;
}
Copy the code

2 Monitor events, prohibit sliding up

This method is more reliable, as the saying goes, the solution must be tied to the bell, the root cause of this problem is caused by touchmove, then fundamentally solve the problem, or start from the event of touchmove. We need to listen for the document touchMove on the mobile and have the preventDefault method to prevent all default actions on the same touch, like scroll events. The thing to be careful about here is when you don’t let it slide, when you let it slide.

<div  ref="root"  ></div>
Copy the code
const box = this.$refs.root
box.addEventListener('touchmove'.function(e){
    /* Let the view container scroll normally */
    e._isScroller = true
})
 /* No sliding up, sliding down */
document.body.addEventListener('touchmove'.function (e) {
    if (e._isScroller) return
    /* Block the default event */
    e.preventDefault()
}, {
    passive: false
})
Copy the code

5. Mobile problems: Input placeholder vertical direction is not centered

background

In the development of mobile terminals, we will encounter input placeholder vertical direction is not in the middle.

The solution

In the placeholder input position, set the text position to be too high. In the placeholder input position, set the text position to be too high. In the placeholder input position, set CSS line-height:normal;

html:

<input class="input"  />
Copy the code

Style:

.input{
   line-height:normal;
}
Copy the code

6 IOS scrolling error -webkit-overflow-scrolling: touch stuck

background

In the process of scrolling up and down the ios page, there will be a lag and not smooth phenomenon. The specific problems are as follows:

1 On Safari, the page occasionally freezes after using -webkit-overflow-scrolling:touch. 2 In Safari, click on another area and slide in the scroll area. The scroll bar does not scroll.

Before we solve this problem, let’s first understand the -webkit-overflow-scrolling attributes

1 Auto: Use normal scrolling. When the finger is removed from the touch screen, scrolling will stop immediately. 2 Touch: Scroll with a rebound effect. When the finger is removed from the touch screen, the content continues to scroll for a while. The speed and duration of continued scrolling is proportional to the intensity of the scrolling gesture. A new stack context is also created.

The solution

<div id="app" style="-webkit-overflow-scrolling: touch; ">
    <div style="min-height:101%"></div> 
</div>
Copy the code

or

<div id="app" style="-webkit-overflow-scrolling: touch; ">  
    <div style="height:calc(100%+1px)"></div> 
</div>

Copy the code

1. Add 1% or 1px height to the next child of the Webkit-overflow-scrolling :touch attribute. The Scrollbar is actively triggered.

7 Mobile Adaptation: Zoom in and out

background

If h5 is not built using a cross-platform framework such as Taro, when displaying H5 on the M side, double click or double click to open the finger page element, and the page will zoom in or out.

In this case, it’s not really a bug, because HTML supports zooming. On the PC, you can control the mouse wheel to zoom in and out of the page, but this behavior also exists on the mobile. But for embedded M-side H5 pages, we don’t need this feature.

The solution

The meta meta tag standard has a medium viewPort property that controls the zoom of the page, usually on mobile.

Let’s first see how taro-H5 fits.

  <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
Copy the code

Core User-Scalable = No, which, yes, blocks scaling behavior.

8 Taro cross-platform development H5: Swiper component horizontal scrolling tile problem

background

When building the H5 application with taro-vue, there was a weird problem with the banner rotation diagram, that is, when the horizontal rotation is expected to be a normal rotation effect, but when initialization, the picture is tiled vertically.

The general effect is as follows:

Expect the result

The actual results

The solution

The general code is as follows:

<swiper  class="swiper-wrap"  >
  <swiper-item
        v-for="(v,idx) in renderList"
        :key="idx"
        class="swiper-item"
    >
        <view class="swiper-wrap-item">
            <image
            mode="widthFix"
            :src="v.path"
            class="swiper-image"
            />
        </view>
    </swiper-item>
</swiper>

Copy the code

The tricky thing is that it doesn’t always recur, and since this page is a product detail page, the problem will occur on a per-product basis. RenderList is a list of images that can be retrieved from behind the scenes, so there is a problem somewhere in the process of rendering a swiper- > request data assignment to renderList -> and then rendering a swiper- > item list. Thus changed the rendering scheme, so use to get data -> render swiper -> render swiperItem scheme.

The improved code looks like this:

<swiper  class="swiper-wrap"  v-if="renderList.length > 0"  >
  <swiper-item
        v-for="(v,idx) in renderList"
        :key="idx"
        class="swiper-item"
    >
        <view class="swiper-wrap-item">
            <image
            mode="widthFix"
            :src="v.path"
            class="swiper-image"
            />
        </view>
    </swiper-item>
</swiper>
Copy the code

After the renderList gets the data, swiper and swiper-item are rendered. That solved the problem.

Wechat applets

The following are compatibility problems encountered during the development of small programs.

1 Android problem: WebView is blocked by wechat

background

In the development of WebView H5 in wechat mini program, when the legal domain name was configured and the domain name was recorded, it was normally opened on ios, but blocked on Android phone. And these cases are all due to open the WebView url there are Chinese characters.

Effect of picture

Analyze the causes and solutions

The actual reason is very simple. If there are Chinese characters in THE HTTP/HTTPS URL of Android phone, encodeURI should be used to encode the Chinese characters.

 <web-view :src="webViewUrl" @message="handerMessage" />
Copy the code
 this.webViewUrl  = commonUrl + '/pages/goods/index? name=' + encodeURI('Alien')
Copy the code

If it’s an interface request, write it this way

wx.request({
   url: commonUrl + '/pages/goods/index? name=' + encodeURI('Alien'),
   method: "GET",})Copy the code

That’s the perfect solution.

Webview is blocked by wechat, detailed solution.

Webview is blocked in wechat mini program. I summarized a detailed program for your reference, is also the development of the pit record.

If in wechat small program development Webview, blocked by wechat, you need to check one by one.

First check whether the domain name is registered

First check whether the domain name is put on record. If the domain name is not put on record, webView cannot be opened normally. If the current domain name is a secondary domain name, it depends on whether the main domain name is put on record.

② Configure the service domain name

Configure the business domain name process is very simple, first login small program background -> development, development management -> development Settings.

Then select the business domain name -> Modify -> Add Business Domain name.

Note the upper part, you need to add as above. After the domain name is successfully added, it is automatically added to the list of legitimate domain names.

③ If (1) and (2) are still intercepted

If you walk the above two steps, you are still intercepted. Domain names before 2020 generally will not be blocked, but wechat is more strict on the new application of domain names, you need to click appeal to try, if the appeal is not good, you need to contact the wechat team to solve the problem, because our company has contact with the wechat team department, so we do not need to contact.

④ If only Android phones are intercepted

If only Android phones are blocked, follow the method above and encode the URL with Chinese characters.

2 iOS problem: wechat small program 1rpx border iOS real machine display incomplete problem

background

If multiple view containers are arranged (both horizontal and vertical directions exist), the problem of incomplete display of individual borders may occur in wechat applet of iPhone of lower version (iphone6, 6P).

The effect is shown below:

<view class="father" >
    <view class="item" >Item 1</view>
    <view class="item" >2 goods</view>
    <view class="item" >Product 3</view>
    <view class="item" >Goods 4</view>
</view>
Copy the code
.father{
    width: 696rpx;
    height: 60rpx; 
    font-size: 28rpx;
    color: #01b5b5;
    margin: 0 auto;  
   }
   .item{
    height: 60rpx;
    line-height: 60rpx;
    border: 1rpx solid #01b5b5;
    float: left;
    border-radius: 10rpx;
    padding: 0 20rpx;
    margin-right: 16rpx;
    margin-bottom: 16rpx;
}
Copy the code

The solution

Width :696rpx in label-con class 692 693 696 697 700 701 704 705 708 709 Let’s divide this set of numbers by 2.

692/2 = 346,693/2 = 346.5, 696/2 = 348,697/2 = 348.5, 700/2 = 350,701/2 = 350.5, 704/2 = 352,705/2 = 352.5, 708/2 = 354,709/2 = 354.5

** This bug occurs when the label’s parent container width (RPX)÷2 is even or even.5, so we can use 200.52=401,3022=604, etc. Then a solution arises.

First: Set the height/width to a safe value

The first way is to set the width of the label’s parent container to a bug-free value, i.e. (odd or odd.5)2, e.g. 2812rpx,281.5*2rpx.

Second: place a 1rpx element placeholder. (Valid for personal test)

<view class="father" >
    <view class="hold" />
    <view class="item" >Item 1</view>
    <view class="item" >2 goods</view>
    <view class="item" >Product 3</view>
    <view class="item" >Goods 4</view>
</view>
Copy the code
.hold{
    width: 1rpx;
    height: 100%;
    float: left;
}
Copy the code

And here’s what it looks like. It solves the problem perfectly.

3 Minor program problem: The scrollview does not slide

background

I believe that many students will encounter the situation that the Scrollview does not slide when developing wechat mini programs. There are many reasons for the scrollview not to slide, and the reasons for horizontal and vertical non-sliding are also different. Next, I will introduce the reasons for horizontal and vertical non-sliding respectively.

Horizontal:

Vertical:

The solution

1 Vertical Direction

For vertical sliding, the causes are as follows:

① Whether the scroll-y of the scroll-view is true

<scroll-view :scroll-y="true" >
  <! -- A lot of things omitted here -->
</scroll-view>

Copy the code

② The height of the scrollview must be set. If the height is not set, or 100% of the height of the parent element is inherited, the vertical direction of the scrollview will be invalid. We have to dynamically get scroll height because we have to get it perfect on all the different phone models

How to get it correctlyscroll-viewhighly

Scroll view in the middle:

const scrollHeight = windowHeight - scrollTop - scrollBottom 
Copy the code

Case 2 Scroll view at the bottom:

const scrollHeight = windowHeight - scrollTop  
Copy the code

③ Check whether the scroll view is overflow-y: auto; And other sliding properties.

<scroll-view :scroll-y="true" class="scroll_box"  >
  <! -- A lot of things omitted here -->
</scroll-view>
Copy the code
.scroll_box{
    height:500px;
    overflow-y: auto;
}
Copy the code

2 Horizontal direction

For horizontal sliding, the causes are as follows:

① Whether the scroll-x of the scroll-view is true

<scroll-view :scroll-x="true" >
  <! -- A lot of things omitted here -->
</scroll-view>
Copy the code

② Do not set display:flex; Let the child set display:inline-block

<scroll-view :scroll-x="true" class="scroll_box"  >
   <view  class="item"  >  <! -- A lot of things omitted here --> </view>
   <view  class="item"  >  <! -- A lot of things omitted here --> </view>
   <view  class="item"  >  <! -- A lot of things omitted here --> </view>
   <! -... -->
</scroll-view>
Copy the code
.scroll_box{
    /* display:flex; Don't do it */
    white-space: nowrap;
}
.item{
   display: the inline - block; /* do this */}Copy the code

③ Scroll view setting style white-space: nowrap;

<scroll-view :scroll-x="true"  style="white-space: nowrap;" ></scroll-view>
Copy the code

4. Lower Versions of Android phones: Native component hierarchy issues

background

This is a project similar to map made a long time ago. On the map component, there is a view. On the advanced version of mobile phone, it will be displayed normally, but on the lower version of Android phone, there will be a view, only text can be seen, the background is completely covered by the native component, and the setting level has no effect.

The solution

Later, after missing the wechat document, I understood the limitations of native components and native components.

Some of the components in the applet are native components created by the client. These components are:

Camera Canvas Input (only displayed as a native component in Focus) Live-player live-pusher map Textarea video

Limitations on native components

Because native components are outside of the WebView rendering process, they have the following limitations when used:

(1) Native components have the highest hierarchy, so no matter how much z-index is set to other components on the page, they cannot be overlaid on native components. The native component inserted after the insertion can override the previous native component.

② Native components are not yet available in picker-View. If the base library is earlier than 2.4.4, native components cannot be used in scroll view, swiper, or movable-view.

③ Some CSS styles cannot be applied to native components, such as: cannot set CSS animation on native components, cannot define native components as position: fixed, cannot use overflow: Hidden in the parent node to cut the display area of native components.

(4) Native component event listener cannot use bind: eventName. Only bindeventName is supported. The native components also do not support catch and Capture event binding. Native components block the debug panel that pops up from the vConsole. In tools, native components are simulated by Web components, so in many cases, the performance of the real machine cannot be well restored. It is recommended that developers debug native components on the real machine as much as possible. *

alternative

Cover-view and cover-image address the highest limitations of the native component hierarchy. The applets specifically provide cover-view and cover-image components that can be overlaid on some of the native components. These two components are also native components, but the usage restrictions are different from the other native components.

5 ios fault: The location element jitter in the wechat Scroll view is abnormal

background

In ios, if there is a position: Absolute element in the Scrollview tag. When the scroll view slides, the positioned elements will shake.

🤔 The cause is caused by the compatibility between Scroll view and ios.

The solution

For this jitter problem, the solution is also very simple, we take the positioning element out of the Scroll view. We can solve this problem at all.

<view class="box" >
    <scroll-view class="scroll_box"  :scroll-y="true" >
        <view class="current" >I'm the location element</view>
    </scroll-view>
</view>
Copy the code
.box{}.scroll_box{
    height:500px;
    overflow-y: auto;
    position:relative;
}
.current{
   position:absolute;
   left:0;
   top:0;
}
Copy the code

to

<view class="box" >
    <scroll-view class="scroll_box"  :scroll-y="true" >
    </scroll-view>
    <view class="current" >I'm the location element</view>
</view>
Copy the code
.box{
    position:relative;
}
.scroll_box{
    height:500px;
    overflow-y: auto;
}
.current{
   position:absolute;
   left:0;
   top:0;
}
Copy the code

6 Wechat applet Jumps to wechat applet. The second hop is invalid

background

In the development of small program, there is a small program jump to another small program scene, the first time there is no problem, but when the jump from the target small program, return to the current small program, the second jump, found that the jump function is invalid, can not jump again. Our jump logic is written in the life cycle of a small application transition page. The specific flow chart is as follows:

The solution

Let’s start with the jump applet method

wx.navigateToMiniProgram({
    appId:'appId'.path:'path'.extraData:'Data that needs to be passed to the applet'.success(){}, // Successful callback
    fail(){}, // Failed callback
    complete(){} // The completion method is executed regardless of success/failure.
})
Copy the code

🤔 Why is this? I have been troubled by this problem for a long time. I have consulted relevant materials and found no solution in wechat documents. But WeChat documents have so a word, and requires the user to trigger jump, beginning 2.3.0 version, if the user did not click on the small program page any position, the developer will not be able to call the interface automatically jump to other small programs Finally found to be in the process of the second jump, because not user active behavior (click events such as human active behavior). It is a jump small program that transitions the life cycle of the page, so a jump judged invalid by wechat will directly follow the failure logic of the jump, and the click jump event in webView is not the active behavior of the user 😂😂.

Therefore, we make a judgment in the transition page. If it is the second jump, the popup window will pop up first, so that the user can click actively to trigger the active behavior of the user. Then jump to the applet.

Taro small program scroll view slide, suddenly placed the top problem

background

When using taro-vue to build a small program, when sliding down the Scroll view, there will be a weird situation, that is, the scroll view will be hidden because of a sibling element display, and suddenly the top.

The structure looks like this.

<view>
    <scroll-view :scroll-y="true" >
       <! -- Much omitted -->
    </scroll-view>
    <view  class="current" v-show="currentShow" > </view>
</view>
Copy the code

When the scrollview slides, we want to use currentShow variable to control the display and hiding of the scrollview, but if currentShow changes, the scrollView will suddenly become the top.

The solution

Taro3.0 taro-vue is not mature enough, there will be a lot of problems, if you want to use taro, I recommend taro2.0 is mature.

Without further ado, here are two solutions.

1 Place the current element node inside the scroll view element.

<view>
    <scroll-view :scroll-y="true" >
       <! -- Much omitted -->
        <view  class="current" v-show="currentShow" > </view>
    </scroll-view> 
</view>
Copy the code

2 Change v-if to V-show

<view>
    <scroll-view :scroll-y="true" >
       <! -- Much omitted -->
    </scroll-view>
    <view  class="current" v-if="currentShow" > </view>
</view>
Copy the code

Cavans small program, generate two-dimensional code problem.

The problem summary

Pit encountered by canvas

(1) Regarding the canvas width, height and zoom ratio, the elements drawn are distorted. Is the height of the canvas really equal to the width and height set by the Cavans tag?

② How does canvas draw two pictures stacked together and control the hierarchy?

③ How to draw multi-line text on Canvas?

④ How to accurately restore the location of each element of the poster according to the design draft.

⑤ How does Canvas draw base64 pictures?

⑥ How to draw a picture of the network, two kinds of Canvas CANVAS API, what is the difference between drawing a picture?

Generate the qr code encountered by the pit

① How to correctly select the generation of TWO-DIMENSIONAL code tools?

The two-dimensional code generated, can not identify how to do?

③ How to draw the LOGO on the TWO-DIMENSIONAL code?

The solution

The answers to these questions can be found in another article of mine, which is sent through the portal:

Recommended collection “small program Canvas poster drawing process

conclusion

These problems are the author encountered in the actual work of the problem, vomiting blood summary trample pit record, in order to let everyone less detours. Send rose, hand left lingering fragrance, reading friends can give the author praise, pay attention to a wave, update the front end of the super core article.

Look back at my previous articles, there are more wonderful content waiting for you!

  • React Advance has eight end-of-the-year optimizations for React developers: 800+ likes 👍

  • Build react, TS scaffolding from 0-1. 300 upvotes 👍

  • Vue component communication mode and its application scenarios 250+ thumbs 👍

  • H5, small program flying into the shopping cart (parabola to draw movement track points) 300 likes 👍

Vue3.0 source code series

  • Vue3.0 responsive principle (super detailed) 200+ like 👍

  • Full analysis of vue3.0 Diff algorithm 100+ like 👍

  • Vue3.0 Watch and Computed source code parsing 30+ like 👍

The react – hooks series

  • React-hooks, custom hooks design patterns and their combat 150+ 👍 like

  • React-hooks how to use 70+ like 👍

Open Source project series

  • React cache page from requirements to open source 230 +Praise 👍

By the way, there will be a second article in the React-Keepalive-Router series to improve features.

The resources

1rpx border ios real machine display incomplete problem analysis and solutions

Official wechat document