LeiHanChenZhou
11/18/2019 - 5:18 PM

可取值的吸附滚动面板

可取值的吸附滚动面板


data: {
  activeRect: {}
},
  
handleTouchEnd: function(e) {
  if (this.timer) {
    clearTimeout(this.timer);
    this.timer = null;
  }
  this.timer = setTimeout(() => {
    wx.createSelectorQuery().selectAll('.item').boundingClientRect().exec(res => {
      const {
        left: activeLeft,
        right: activeRight
      } = this.data.activeRect;
      for (const {
          left,
          right,
          id
        } of res[0]) {
        if (activeLeft <= left && activeRight >= left) {
          console.log(`id: ${id} is actived`)
        }
      }
    })
  }, 500)
},

onLoad() {
  // ...
  
  wx.createSelectorQuery().select('#target').boundingClientRect().exec(res => {
    const {
      left,
      right,
      top,
      bottom
    } = res[0]
    this.setData({
      activeRect: {
        left,
        right,
        top,
        bottom
      }
    })
  });
  
  // ...

}
<view class="wrapper">
  <view class="target" id="target" />
  <view class="container" dir="ltr" wx:if="{{activeRect}}" bind:touchmove="handleTouchEnd">
    <view class="item" id="item_1" >1</view>
    <view class="item" id="item_2" >2</view>
    <view class="item" id="item_3" >3</view>
    <view class="item" id="item_4" >4</view>
    <view class="item" id="item_5" >5</view>
    <view class="item" id="item_6" >6</view>
    <view class="item" id="item_7" >7</view>
    <view class="item" id="item_8" >8</view>
  </view>
</view>
.container {
  width: 100%;
  display: flex;
  flex-flow: row nowrap;
  overflow: auto;
  outline: 1px dashed lightgray;
  scroll-snap-type: x mandatory;
  position: relative;
}

.target {
  content: '';
  position: absolute;
  left:33%;
  right: 33%;
  top: 0;
  display: block;
  /* border: 1px solid red; */
  height: 100%;
  width: 33%;
}


.item {
  scroll-snap-stop: always;
  text-align: center;
  scroll-snap-align: center;
  flex: none;
  font-size: 64px;
  width: 33%;
}

思路

  1. 先利用css实现吸附滚动面板效果
  2. 在滚动面板外加上容器并且为滚动面板添加一个“标尺”节点
  3. 在主页面加载后获取“标尺”节点的 boundingClientRect 信息并存储
  4. 为滚动面板容器添加 touchMove 事件监听,在触发时重新计算每个子项是否满足标尺的要求,满足的标记为激活项,注意防抖

经过上述步骤即可获取到该组件滚动后的取值

还需改进的地方

  1. 可受控
  2. 可通过点击子项自动滚动到激活标尺
  3. 临界项暂时无法被选中