最近在学习小程序,实现了左右联动的功能,记录一下思绪,方便以后参考。
最终的界面如下, 点击左边任意一个项目,右边会跳到相应项目的起始位置,右边滑动,左则会跳到相应的位置。
在这里,右则每一项的高度都是固定的,方便定位当前滑动距离在哪一个大项(左则)里。右则的 scroll-view 使用了一项关键的属性:scroll-into-view,这个属性用来确定 scrollTop 的值的,当 scroll-into-view 的值和 scroll-view 里面的元素的id的值相等时,scroll-view 会定位到该元素,scrollTop 的值就是滑动到该元素的值。
做这个功能的时候,遇到一个问题,就是右则的小项种类不多的时候,例如某个类目只有1~2个,那么点击左则的大项的时候,会出现点击不到的现象。这里可以用点小技巧来解决:
点击左则大项的时候,设置当前点击标记为true,设置 classifySeleted 为当前点击的项目。 然后在滑动触发函数(onGoodsScroll)里面,判断当前触发滑动是否点击产生的,如果是,则不设置 classifySeleted 的值,否则就计算 classifySeleted 的值并设置。
wxml代码如下:
1 <view class="content-container"> 2 <scroll-view class="classify-container" scroll-y="true"> 3 <view class="classify {{classifySeleted==classify.typeId?'active':''}}" wx:for="{{cakeTypes}}" wx:for-item="classify" wx:key="id" data-id="{{classify.typeId}}" bindtap="tapClassify"> 4 <view class="name">{{classify.typeName}}</view> 5 </view> 6 </scroll-view> 7 <scroll-view class="goods-container" scroll-y="true" scroll-into-view="{{'inToView' + typeIndex}}" bindscroll="onGoodsScroll" scroll-top="{{scrollTop}}"> 8 <view wx:for="{{cakeTypes}}" wx:for-item="classify" wx:key="id"> 9 <view class="title" id="{{'inToView'+classify.typeId}}">{{classify.typeName}}</view> 10 <view class="goods" wx:for="{{classify.productIds}}" wx:for-item="cake" wx:key="id"> 11 <image class="pic" src="{{cake.imgSrc}}" data-src="{{cake.imgSrc}}" data-list="{{cake.imgSrc}}" bindtap="tapImg"></image> 12 <view class="name ellipsis">{{cake.name}}</view> 13 <view class="sold">{{cake.introduce}}</view> 14 <view class="price">¥{{cake.price}}</view> 15 </view> 16 </view> 17 </scroll-view> 18 </view>
js代码如下:
1 onGoodsScroll: function (e) { 2 3 var scrollTop = e.detail.scrollTop; 4 var h = 0; 5 var classifySeleted = this.data.classifySeleted; 6 var titleHeight = Math.ceil(70 * this.data.percent); 7 var itemHeight = Math.ceil(180 * this.data.percent); 8 9 this.data.cakeTypes.forEach(function (classify, i) { 10 console.log("h:" + h + " scrollTop:" + scrollTop); 11 var _h = titleHeight + classify.productIds.length * itemHeight; 12 if (scrollTop >= h - 10) { 13 classifySeleted = classify.typeId; 14 } 15 h += _h; 16 }); 17 18 if (this.data.isTap) { 19 this.setData ({ 20 isTap: false 21 }) 22 } else { 23 this.setData({ 24 classifySeleted: classifySeleted 25 }); 26 } 27 }, 28 29 tapClassify: function (e) { 30 var id = e.target.dataset.id; 31 this.setData({ 32 isTap: true, 33 classifySeleted: id, 34 typeIndex: id 35 }); 36 },