小程序组件开发:实现自动滚动的 scroll-into-center 组件
2024-11-03 09:57 阅读(170)

小程序组件开发:实现自动滚动的 scroll-into-center 组件

在小程序开发中,我们经常会遇到需要滚动视图自动滚动到指定位置的需求。今天,我将带大家一起实现一个名为 scroll-into-center 的小程序组件,该组件可以帮助我们轻松实现这一功能。

效果图

组件结构

首先,我们来看一下 scroll-into-center 组件的文件结构:

components/
  scroll-into-center/
    index.json
    index.less
    index.ts
    index.wxml

属性

activeId


类型: String

默认值: ''

描述: 当前激活的元素 ID,当该属性变化时,组件会自动滚动到对应的元素位置。


数据字段

_scrollInfo


prevDistance: 上一次滚动的距离

screenHalfWidth: 屏幕宽度的一半

subLeft: 子元素左边距

subHalfWidth: 子元素宽度的一半


方法

getRect(activeId: string, retryCount = 1)

该方法用于获取指定元素的宽高和位置信息,并更新 _scrollInfo 数据字段。如果获取失败,会进行最多 5 次重试。

moveTo()

该方法根据 _scrollInfo 数据字段计算需要滚动的距离,并更新 scrollLeft 数据字段,使滚动视图滚动到指定位置。

handleScroll(e: WechatMiniprogram.ScrollViewScroll)

该方法用于记录滚动视图的滚动距离。

使用示例

在页面的 WXML 文件中引入 scroll-into-center 组件:

<scroll-into-center activeId="{{activeId}}" />

在页面的 JS 文件中设置 activeId 属性:


Page({
  data: {
    activeId: 'item1',
  },
  onLoad() {
    // 设置 activeId 以触发滚动
    this.setData({
      activeId: 'item2',
    })
  },
})

组件实现细节

接下来,我们详细讲解一下 scroll-into-center 组件的实现细节。


组件定义

在 index.ts 文件中,我们定义了组件的属性、数据字段、生命周期函数和方法:

Component({
  options: {
    pureDataPattern: /^_/, // 指定所有 _ 开头的数据字段为纯数据字段
  },
  properties: {
    activeId: {
      type: String,
      value: '',
    },
  },
  data: {
    _scrollInfo: {
      prevDistance: 0,
      screenHalfWidth: 0,
      subLeft: 0,
      subHalfWidth: 0,
    },
  },
  observers: {
    activeId(activeId) {
      console.log(activeId)
      this.getRect(activeId)
    },
  },
  lifetimes: {
    attached() {
      const query = wx.createSelectorQuery().in(this)
      query
        .select('.scroll-view')
        .boundingClientRect(rect => {
          if (rect) {
            this.setData({
              '_scrollInfo.screenHalfWidth': rect.width / 2,
            })
          }
        })
        .exec()
    },
  },
  methods: {
    getRect(activeId: string, retryCount = 1) {
      const query = wx.createSelectorQuery()
      query
        .select('#' + activeId)
        .boundingClientRect(rect => {
          if (!rect) {
            if (retryCount > 5) return
            console.log('retry', retryCount)
            setTimeout(() => {
              this.getRect(activeId, retryCount + 1)
            }, 100)
            return
          }
          const _scrollInfo = {
            ...this.data._scrollInfo,
            subLeft: rect.left,
            subHalfWidth: rect.width / 2,
          }
          this.setData({
            _scrollInfo,
          })
          this.moveTo()
        })
        .exec()
    },
    moveTo() {
      const { subLeft, subHalfWidth, prevDistance, screenHalfWidth } = this.data._scrollInfo
      const needScroll = subLeft - screenHalfWidth + subHalfWidth
      const scrollLeft = needScroll + prevDistance
      this.setData({
        scrollLeft: scrollLeft,
      })
    },
    handleScroll(e: WechatMiniprogram.ScrollViewScroll) {
      const distance = e.detail.scrollLeft
      this.data._scrollInfo.prevDistance = distance
    },
  },
})

属性 activeId

activeId 属性用于指定当前激活的元素 ID。当该属性变化时,组件会自动调用 getRect 方法获取指定元素的位置信息,并滚动到该位置。

数据字段 _scrollInfo

_scrollInfo 数据字段用于存储滚动视图和子元素的位置信息,包括上一次滚动的距离、屏幕宽度的一半、子元素左边距和子元素宽度的一半。

方法 getRect

getRect 方法用于获取指定元素的宽高和位置信息,并更新 _scrollInfo 数据字段。如果获取失败,会进行最多 5 次重试。获取成功后,会调用 moveTo 方法进行滚动。

方法 moveTo

moveTo 方法根据 _scrollInfo 数据字段计算需要滚动的距离,并更新 scrollLeft 数据字段,使滚动视图滚动到指定位置。

方法 handleScroll

handleScroll 方法用于记录滚动视图的滚动距离,并更新 _scrollInfo 数据字段中的 prevDistance。

总结

通过以上步骤,我们实现了一个功能强大的 scroll-into-center 组件。该组件可以帮助我们在小程序中轻松实现滚动视图自动滚动到指定位置的功能。

希望这篇文章对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言讨论。


作者:毛利南

链接:https://juejin.cn