《scrollTop VS scrollLeft 之微信小程序》

背景

公司使用微信小程序来开发公司的一个产品,有幸参与到其中。在最近的一次迭代中,体验优化有这样一个点,点击类目时,分别实现横向滚动和纵向滚动的中间定位:

技术方案

横向滚动

一、wxml-核心代码

    <scroll-view
      class="{{showFold ? 'subC-top-nav-fold' : 'subC-top-nav'}}"
      enhanced="{{true}}"
      bounces="{{true}}"
      scroll-anchoring="{{true}}"
      scroll-x="{{true}}"
      scroll-with-animation="{{true}}"
      scroll-animation-duration="100"
      enable-flex="{{true}}"
      scroll-left="{{scrollLeft}}"
    >
      <view class="subC-container">
        <view
          class="subC-content"
          wx:for="{{subList}}"
          wx:key="id"
          id="tab_{{item.id}}"
          data-item="{{item}}"
          data-key="secondarycategorylist-{{currentInfo.categoryId}}-{{item.id}}"
          catchtap="changeSubCategory(item,index)"
        >
          <view class="tabs-item g-column g-center report-expo">
            <image class="{{currentInfo.subCategoryId == item.id ? 'image-selected' : 'item-image'}}" mode="aspectFit" src="{{item.picUrl}}"></image>
            <text class="{{currentInfo.subCategoryId == item.id ? 'item-text-selected': 'item-text'}}">{{ item.name }}</text>
          </view>
        </view>
      </view>
    </scroll-view>

二、wxs-核心代码

    changeSubCategory(item, index) {
      // 计算横向滚动位置
      this.computedScrollLeft(index)
    },
    // 计算横向滚动位置
    computedScrollLeft(index) {
      const windowWidth = getApp().globalData.ww
      if (this.subList.length > 3) {
        if (index < 2) {
          this.scrollLeft = 0
        } else {
          this.scrollLeft = ((index - 2) * 134 * windowWidth) / 750
        }
      }
    },

纵向滚动

一、wxml-核心代码

    <scroll-view
      class="leftNav-area"
      style="width: 100%; height: 100%"
      enhanced="{{true}}"
      bounces="{{true}}"
      scroll-with-animation="{{true}}"
      scroll-anchoring="{{true}}"
      scroll-animation-duration="100"
      scroll-y="{{true}}"
      scroll-top="{{scrollTop}}"
    >
      <view
        wx:for="{{categorys}}"
        wx:key="categoryCityId"
        class="topC-leftNav-item {{item.categoryCityId === currentCategoryCityId? 'focus' : ''}}"
        id="category_{{item.id}}"
        data-index="{{index}}"
        catchtap="selectNav(item, index)"
        data-item="{{item}}"
        data-activeIndex="{{index}}"
      >
        <view class="focus-slide"></view>
        <image class="topC-leftNav-item-icon" wx:if="{{item.iconUrl}}" src="{{item.iconUrl}}"></image>
        <text>{{ item.name }}</text>
        <view class="corner top-corner"></view>
        <view class="corner bottom-corner"></view>
      </view>
      <view class="{{topcClass}}" wx:class="{{currentCategoryCityId === bottomCategoryCityId ? 'settle-bar-radius': ''}}"></view>
    </scroll-view>

二、wxs-核心代码

    selectNav(item, index) {
      // 计算纵向滚动位置
      this.computeMidScrollTop(index)
    },
    // 计算纵向滚动位置
    computeMidScrollTop(index) {
      // 滚动位置---------------start---------------------------------
      const windowHeight = getApp().globalData.hh
      const midIndex = Math.floor((windowHeight - 130) / (46 * 2))
      const leftCategroy = this.categorys.length - index + 1
      if (index < midIndex && leftCategroy > index) {
        this.scrollTop = 0
      } else {
        this.scrollTop = (index + 1 - midIndex) * 60
      }
    }

思考

需要注意的是,在微信小程序开发,需要有rpx和px的换算

最初的实现方案是:https://www.cnblogs.com/langxiyu/p/13159055.html,「在本项目中由于兼容性,放弃掉」

实现原理是:

效果一: 可直接使用 scroll-into-view 属性实现  或者 也可使用  scroll-left

思路:第一种, scroll-into-view 绑定一个动态 ID,子元素循环产出ID,点击时进行绑定(这次就不做代码产出了)

           第二种, 计算每个子元素的宽度,点击时获取当前点击元素前面的元素宽度之和

 

效果二:使用  scroll-left

思路:计算每个子元素的宽度,点击时获取当前点击元素索引 - 1 的前面元素宽度之和,相比于效果一的第二种情况,这里少算当前点击元素前面的一个元素的宽度,实现留一

 

效果三:使用  scroll-left

思路:当前点击子元素距离左边栏的距离 - scroll-view 宽度的一半  + 当前点击子元素一半的宽度 实现居中展示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值