Slide right letter index of wechat applet

We often see this in wechat and address book. How to implement this function in the applet (wait, we need to use an official component of the applet). This function can be divided into two parts, one is the rolling area and the other is the sliding positioning area.

realization
Scroll area
In the applet, scroll to the specified position can be realized by using the scroll view component (click me to view the applet document)

<scroll-view class="goup_list" scroll-with-animation="true" scroll-y="true" style="height: 300rpx;" scroll-into-view="{{toView}}">
    <Specific business interface code />
</scroll-view>

At the end is the code I just recorded for GIF. You can see that the scroll view component has a property scroll into view, which can jump to the specified location. The value is ID, which is the ID of B, C and D seen by GIF.

(there will be complete code at the end)

Sliding implementation
When sliding, we will think of the touchmove event. We need to rely on this to determine which index (letter) to slide to.

But the slide doesn't directly tell you which component it is, so we need to use the existing information. Here we use the information of Y and X.

The logic after getting X and Y is as follows

It's hard to describe clearly in words. Look at the figure below. You can calculate the deviation value in this way, and then divide it by the height of each item to get the number of items to slide to. Another problem involved here is how to find the height of a single item. Height / number.

code

var y = e.touches[0].pageY;
    var itemLen = this.data.list.length
    var height = letterDomRes.height
    var top = letterDomRes.top
    // Offset of sliding (deviation value)
    var offsetTop = (height + top - y)
    var itemHeight = height / itemLen
    var index = itemLen - ((offsetTop / itemHeight)|0) - 1
    if(index < 0 || index >= itemLen){
      return
    }

There is also where the above data comes from, that is, how the applet takes the top value and height in the figure below.

code

//Create node selector
var query = wx.createSelectorQuery()
query.select('.letter-index').boundingClientRect()
query.exec(function (res) {
      letterDomRes = res[0]
      console.log(letterDomRes);
})

letterDomRes.height letterDomRes.top {is the data we need.

It's all done here. Then add an optimization. If it exceeds the sliding range, return. The above code also has it. Then judge whether it is during sliding when setting. If yes, filter the same settings.

Complete code
JS

// pages/word/strange.js
var letterDomRes = {}
var moveing_word = ''
Page({

  /**
   * Initial data of the page
   */
  data: {
    toView: '',
    list: [
      {
        word: 'B',
        children: [
          {word: 'Ban', translation: 'vt. Ban, ban; n. Prohibition'},
          {word: 'Ban', translation: 'vt. Ban, ban; n. Prohibition'},
          {word: 'Ban', translation: 'vt. Ban, ban; n. Prohibition'},
        ]
      },
      {
        word: 'C',
        children: [
          {word: 'Ban', translation: 'vt. Ban, ban; n. Prohibition'},
          {word: 'Ban', translation: 'vt. Ban, ban; n. Prohibition'},
          {word: 'Ban', translation: 'vt. Ban, ban; n. Prohibition'},
        ]
      },
      {
        word: 'D',
        children: [
          {word: 'Ban', translation: 'vt. Ban, ban; n. Prohibition'},
          {word: 'Ban', translation: 'vt. Ban, ban; n. Prohibition'},
          {word: 'Ban', translation: 'vt. Ban, ban; n. Prohibition'},
        ]
      },
    ]
  },
  // ---- methods
  letterTap(e){
    var id = e.target.id
    // console.log(id)
    this.setListSite(id)
  },
  letterMove(e){
    var y = e.touches[0].pageY;
    var itemLen = this.data.list.length
    var height = letterDomRes.height
    var top = letterDomRes.top
    // Offset of sliding (deviation value)
    var offsetTop = (height + top - y)
    var itemHeight = height / itemLen
    var index = itemLen - ((offsetTop / itemHeight)|0) - 1
    if(index < 0 || index >= itemLen){
      return
    }
    var letter = this.data.list[index].word
    // console.log(index, letter)

    // [optimization] filter the same
    if(moveing_word == letter){
      return
    }
    moveing_word = letter
    this.setListSite('word_' + letter)
    // console.log(height / this.data.list.length)
    //  / this.data.list.length
    // console.log(letterDomRes.top)
  },
  letterEnd(e){
    // Reset
    moveing_word = ''
  },
  /**
   * Set scroll position
   * @param {String} id Prefix + letter
   */
  setListSite(id){
    wx.showToast({
      title: id.split('_')[1],
      icon: 'none',
    })
    this.setData({
      toView: id,
      duration: 500,
    })
  },
  /**
   * Life cycle function -- listening for page loading
   */
  onLoad: function (options) {
  },

  /**
   * Life cycle function -- monitor the completion of the first rendering of the page
   */
  onReady: function () {
    //Get index bar height in onshow
    var query = wx.createSelectorQuery();//Create node selector
    query.select('.letter-index').boundingClientRect()
    query.exec(function (res) {
      //res is an array of information for all elements labeled mjltest
      letterDomRes = res[0]
      console.log(letterDomRes);
      //Take height
      console.log("height : "+res[0].height);
    })
  },

  /**
   * Life cycle function -- monitor page display
   */
  onShow: function () {

  },

  /**
   * Life cycle function -- listening for page hiding
   */
  onHide: function () {

  },

  /**
   * Life cycle function -- listen for page unloading
   */
  onUnload: function () {

  },

  /**
   * Page related event handler -- listen to user drop-down actions
   */
  onPullDownRefresh: function () {

  },

  /**
   * Handler for bottom pull event on page
   */
  onReachBottom: function () {

  },
})

WXML

<!--pages/word/strange.wxml-->
<view class="container">
    <scroll-view class="goup_list" scroll-with-animation="true" scroll-y="true" style="height: 300rpx;" scroll-into-view="{{toView}}">
        <view class="">
            <view class="group_item" wx:for="{{list}}" wx:key="{{index}}">
                <view class="group">
                    <view class="title" id="word_{{item.word}}">{{item.word}}</view>
                    <view class="word_list">
                        <view class="word_list_item" wx:for="{{item.children}}" wx:key="{{index}}">
                            <view class="e">
                                <view>{{item.word}}</view>
                                <view class="">{{item.translation}}</view>
                            </view>
                            <image mode="widthFix" src="/image/right.png" class="right-image" />
                        </view>
                    </view>
                </view>
            </view>
        </view>
    </scroll-view>
    <view class="letter-index" bind:touchmove="letterMove" bindtap="letterTap" bind:touchend="letterEnd">
        <view class="item" id="word_{{item.word}}" wx:for="{{list}}" wx:key="index">{{item.word}}</view>
    </view>
</view>

If you also want to develop small programs or websites, you can help you realize your development needs through a third-party professional development platform: Xiamen cares about technology -Focus Xiamen applet development , APP development, website development

Keywords: Mini Program

Added by remnant on Mon, 03 Jan 2022 14:04:10 +0200