taro applet add skeleton screen

Keywords: Javascript

Recently, we have done some small program performance optimization, such as subcontract loading, adding skeleton screen and so on. This time, we mainly talk about the relevant content of skeleton screen.
There are three methods for skeleton screen:
1. Directly ask the UI students to help P-map, and put it as a loading map. This method is simple and crude, but it needs help~
2. According to each page, write a set of the same code to cover the style. The quantity of this method, you know~
3. Can I write a component? The component automatically obtains the location and size information of the element to render, and unloads the data after it returns.

Let's talk about the third method~
The main framework adopts taro, a set of codes are compatible with multiple ends, but today's codes need to consider compatibility~
According to the above ideas, we first need to find the container of the skeleton screen, then find the element that needs to be P-gray, obtain the location and size information of the element, and finally render~
Get the element. taro provides the API, Taro.createSelectorQuery() . Return an instance of the SelectorQuery object through the API, and then pass the selectAll() To find the class name of a specific class in the skeleton. After searching, click boundingClientRect() Get the location and size information of the element, and store the information in the array.
I have written two classes here, one is skeleton radius, rendering circle; the other is skeleton rect, rendering rectangle. You can expand it later.
There are a lot of words. You may see them in the clouds. Here's the code~
`

    // Baidu applet currently does not support descendant selectors across custom components: > >
    // However, when H5 uses the descendant selector (. The ancestor. The descendant), it can automatically identify the descendant within the custom component
    // Wechat applet supports generation selectors across custom components (. The ancestor > >. The descendant), which can be modified as follows. ${this. Props. Selector} > >. ${this. Props. Selector} - radius`
    if (process.env.TARO_ENV === 'weapp') {
        Taro.createSelectorQuery().selectAll(`.${this.props.selector} >>> .${this.props.selector}-radius`)
            .boundingClientRect().exec(rect => {
                that.setState({
                    radiusList: rect[0]
                });
            });
    }
    else {
        Taro.createSelectorQuery().selectAll(`.${this.props.selector} .${this.props.selector}-radius`)
        .boundingClientRect().exec(rect => {
            that.setState({
                radiusList: rect[0]
            });
        });
    }

`
You can also see the note above. If you want to run on multiple terminals, you can judge the environment first and use different selectors according to the environment. The above code is to realize a circular gray area. If you need more than one shape, you can simply encapsulate a function. I will not go into details here. You can go to Demo Detailed view~
Let's talk about the compatibility of descendant selectors:

  1. Baidu applet currently does not support cross custom component descendant selector: > >.
  2. But when H5 uses the descendant selector (. The ancestor. The descendant), it can automatically identify the descendant within the custom component. When a custom component is used, whether there is element wrapping in the outer layer can recognize the specified class selector inside the custom component.
  3. Wechat applets support the descendant selector (. The ancestor > >. The descendant) across custom components, but when using custom components, the outer layer cannot nest elements, otherwise it cannot be recognized.

The next step is rendering. This is relatively simple. Go to the code directly. Here, the background color and the background color of the elements to be P-shaped can be passed in or not when using components. There is a default color~
`

  <View className='skeleton-container' style={{background: `${bgColor}`}}>
            {
                radiusList.map(radiusItem => (
                    <View className='skeleton-item skeleton-item-radius' style={{width: `${radiusItem.width}PX`, height: `${radiusItem.height}PX`,
                        background: `${itemColor}`, top: `${radiusItem.top}PX`, left: `${radiusItem.left}PX`}}
                    />
                ))
            }
            {
                rectList.map(rectItem => (
                    <View className='skeleton-item' style={{width: `${rectItem.width}PX`, height: `${rectItem.height}PX`,
                        background: `${itemColor}`, top: `${rectItem.top}PX`, left: `${rectItem.left}PX`}}
                    />
                ))
            }
        </View>

`
Here, the component has been completed. When using, you can directly import the component, and then pass it to the selector. Note that since the data is obtained dynamically and the page starts to be empty, you need to mock some fake data to fill the page. The element class name to be covered must be consistent with the graphic class in the component~
`

   <View className='container' style={{fontSize: '20PX'}}>
            {
                showSkeleton && <Skeleton
                    selector='skeleton'
                    bgColor='pink'
                    itemColor='skyblue'
                />
            }
            <View className='skeleton'>
                <View className='userInfo'>
                    <Image
                        src={userInfo.avatarUrl}
                        alt='User head'
                        className='userInfo-avatar skeleton-radius'
                    />
                    <Text>{userInfo.nickName}</Text>
                </View>
                <View>
                    {
                        list.map(item => (
                            <View className='skeleton-rect' style={{marginBottom: '30PX'}}>{item}</View>
                        ))
                    }
                </View>
                {/* It is better not to wrap the outer layer of the custom component, otherwise the wechat applet cannot recognize it, but H5 can recognize it */}
                <List />
            </View>
        </View>

`
See the comments? When using the custom component, please note that if the custom component is reported wrong by the element, the wechat applet cannot recognize the graphic class in the custom component!!!

Finally, I want to talk about the scene suitable for skeleton screen: the page structure is simple, and the width and height of the elements are fixed ~ if the width and height of the elements are not fixed, the mock fake data you write may have a large gap with the actual rendered page, such as waterfall flow~

Well, here are some of the gains of this time. If you have a better way, you can leave a message and communicate. Finally, attach the complete Code address~

Posted by BigBrother on Thu, 14 Nov 2019 19:15:21 -0800