Yesterday in imitation jingdong shopping small program, its “my” interface head pull down gradient effect is very cool, so I studied, to share with you my research process ~~

1. My interface of JD Shopping mini program

Here’s what it looks like (it’ll take a little while to load, but here’s the GIF) :



2. Overall layout

Look at the GIF, the head navigation bar of JD shopping small program is certainly not the default head of small program, by adding “navigationStyle”:” Custom “in the window item of the small program. Json configuration file, you can customize the top navigation bar of small program;

Analyzing the “my” interface, we can see that the background image of the head navigation bar and the picture below must be the same picture, but it is divided, part of the top, part of the bottom;

We use the CSS background to place the background image and position the background image. It is easy to put the image in two different boxes and make a complete image.

In the GIF, we can see that the main body of the interface is a scrollable area, which can be achieved by using the small program’s Scrollview component

So here’s the layout:



3. Gradient scheme

Now that the basic framework is set up, how do you implement a gradient for the header navigation bar to follow the body scroll? Just listen to the interface body scroll event, get the current scroll position, and then change the state of the head navigation bar background according to the position on the line;

In fact, the small program scrollView provides a method to listen for scroll events. We only need to write a JS function to get the current position of the interface body in real time.

How do you change the background of the navigation bar when you get the current scroll position of the body of the interface? My first thought was the following:

  1. A background image, a background color, and then the background color gradually appears, gradually occludes the background image;

    (in fact, this scheme does not work, because the CSS background property of the background-color and background-image can not customize the layer, the background color below the background image, can not make the background color to the top;)

Then I thought of using the opacity property of CSS. I could set opacity:0 to make the background image gradually disappear; And the miniprogram uses Mustache to provide a data binding method for pages and JS; So you can finally tie the background state of the header navigation bar to the current scrolling position of the interface body;

It will look like this (it will take a while to load, but the GIF is below) :

Here’s the code:

<! --me. WXML file --> <view class="page"> <! > < img style="opacity: {{opacity}}; ></view> <! Since the opacity of all contents inside the box changes, install the header navigation bar's name on another View, and then use Position to remove it from the stream. <view class="hd-text"> my </view> </view> <! <view class="page-bd"> <! < span style="height: 90vh; height: 90vh; bindscroll="scrollPage"> <view class="me-container"> <view class="me-hd">1</view> <view class="me-bd">2</view> </view> </scroll-view> </view> </view>Copy the code
/*me. WXSS file */. Page {height: 100vh; width: 100vw; display: flex; flex-direction: column; Page -hd{height: 10vh; width: 100%; } .hd-background{ width: 100%; height: 100%; background: url(https://636c-cloud1-5gfii8jlc56b5045-1306536140.tcb.qcloud.la/wxfile/background.png? sign=6a62c2c13c024f0091a1f8034f4d6155&t=1627552695) ; background-repeat: no-repeat; background-size: 100vw; } .hd-text{ position: relative; width: 100%; text-align: center; top: -50rpx; } /* interface body */. Page -bd{flex:1; } .me-container{ height: 100%; width: 100%; } .me-hd{ width: 100vw; height: 40vh; background-image: url(https://636c-cloud1-5gfii8jlc56b5045-1306536140.tcb.qcloud.la/wxfile/background.png? sign=6a62c2c13c024f0091a1f8034f4d6155&t=1627552695); background-repeat: no-repeat; background-size: contain; background-position: 0 -10vh; } .me-bd{ height: 100vh; }Copy the code
Data: {opacity:1}, scrollPage(e){let scrollTop = e.dietail.scrollTop; if(scrolltop > 150){ this.setData({ opacity:0 }) return ; } this.setData({ opacity: (150 - scrolltop) / 150 }) },Copy the code


4, test,

As mentioned above, a small BUG was found after the test. When scrolling slowly up and down, the background image of the header navigation bar would change smoothly. However, when scrolling quickly down, the page body had reached the top, but the header navigation bar could not restore the opacity state, as follows:

After the test, it was found that the scroll event of scroll-view did not follow the scrolling of the screen, although the scroll area had reached the top after the rapid pulldown and the finger was removed from the touch screen in the middle.

The scrollTop parameter of each Scroll event is tested as follows. When the last scroll event occurs, the scrollTop value is 113, but does not change to 0.

In my js, the opacity of the navigation bar does not change to 1 because it is related to the size of the scrollTop parameter returned by the event object when the scroll event occurs. Only when scrollTop is 0, the opacity of the navigation bar does not change to 1.

5, improve

After discovering the BUG, I tried several things:

  1. Use bindDRAGGING to bind the sliding event

    The difference between Binddragging and Bindscroll is that Binddragging is binding to a sliding event while bindscroll is binding to a rolling event. The difference between a sliding event and a rolling event is that a sliding event can only take effect on the mobile end, and cannot be slid on the PC end. Scrolling events can be rolled on PC, and the performance of sliding events and scrolling events on mobile end is the same;

    Therefore switching to Binddragging does not solve the problem;

  2. Add the bindToupper binding scroll to the top event based on the bindScroll binding scroll event

    No, the BindToupper event will not be triggered when a quick drop is made;

  1. After using the methods of slectorQuery objects

    The select method of slectorQuery object is used to obtain the height of the node from the top of the screen, and the opacity of the header navigation bar is dynamically changed based on the height. This still requires the scroll event to be triggered to work.

  2. The Scrolltop of the Scrollview is bidirectional bound

    No, scrollview cannot be bidirectional bound;

  3. Is there any way to get the position of the scroll in real time or the height of the view component corresponding to me-HD from the top in real time

    Not found, onLoad(), nShow(), onReady() and other event listening functions are only executed once throughout the page life cycle;

  4. Turn off rolling inertia

    No, scrolling can only be turned off on ios, and it will greatly affect the user experience, so you can’t turn it off.

  5. Based on the changes of the bindScroll bound scroll event, the scroll trend and logic are obtained in JS. If you can determine whether the scroll event is a rapid pulldown, set the opacity on the navigation bar in the header to 1.

    This method also requires that after the bindScroll event occurs, the parameters returned by each event object should be recorded and their change rule should be counted. This method relies on the data returned by the event object. The sharp change of data does not necessarily correspond to the action of sharply scrolling down to the top. So it’s not good enough;


Final conclusion:

After a day of research, the root cause of the BUG is still that the bindScroll event does not trigger when scrolling down quickly. In the wechat developer community, we have seen some people have the same problem: Bindscrolltolower occasionally does not trigger when scrolling down quickly?

A guess:

The capture of the scroll event in the miniprogram was throttled so that my scroll was faster than the capture, so the view went back to the top, and the scroll event was not captured;

But I tested the JINGdong shopping small program fast scroll down, the head navigation bar background picture can be restored ~_~; Have the small program development personnel of JINGdong to solve puzzled!

6. Extended data

  1. scroll-viewThe use of;
  2. slectorQueryObject;