上一篇:《微信小程序-商品列表左=>右聯(lián)動(一)》
上一篇講解了左=>右聯(lián)動,那個還比較簡單,本篇寫剩下比較核心的部分,也是本次開發(fā)過程中遇到最難的部分,右=>左聯(lián)動,先簡單看一下演示

右左聯(lián)動.gif
一、關鍵技術:
(1) 小程序 wxss 中使用 rpx,而 js 中 scrollTop 獲取到的值是 px,所以存在rpx 轉 px 的問題。以 iPhone6 為基準,轉換公式:
// percent 為當前設備1rpx對應的px值
var percent = res.windowWidth / 750;
詳情參考:WXSS尺寸單位
(2) 微信自帶scroll-view UI組件,通過 bindscroll="scroll" 綁定滾動事件;通過 scroll-top="{{scrollTop}}" 動態(tài)控制 左側滑欄的被動滾動。
二、實現(xiàn)思路:
通過計算整個右側滑欄滾動上去的高度 與 右側滑欄中每一個分類距頂部的距離做比對,獲取到該滾動置頂?shù)姆诸惖?index 。然后用獲取到的 index 乘以左側滑欄中某一項的高度,動態(tài)賦值給左側滑欄內的 scrollTop ,控制左側滑欄的聯(lián)動。

圖片發(fā)自簡書App
以下是代碼,考慮到部分新手同學,幾乎為每一行代碼添加了注釋。
wxml代碼:標簽中屬性如有不懂,請自行查看小程序API,內有詳細講解!
<view class="container">
<!--左側欄-->
<scroll-view class='scroll_left' scroll-y="true" style="height:{{winHeight}}px;" scroll-with-animation="true" scroll-top="{{scrollTop}}">
<view class="nav_left">
<block wx:for="{{list}}" wx:for-index="idx" wx:for-item="itemName" wx:key="*this">
<!--當前項的id等于item項的id,那個就是當前狀態(tài)-->
<!--用data-index記錄這個數(shù)據(jù)在數(shù)組的下標位置,使用data-id設置每個item的id值,供打開2級頁面使用-->
<view class="nav_left_items {{curNav == idx ? 'active' : ''}}" bindtap="switchRightTab" data-index="{{index}}" data-id="{{item.id}}" id="{{idx}}">{{itemName[0].title}}</view>
</block>
</view>
</scroll-view>
<!--右側欄-->
<scroll-view scroll-y="true" class="scroll_right" style="height:{{winHeight}}px;" scroll-into-view="{{scrollTopId}}" scroll-with-animation="true" bindscroll="scroll">
<view class="nav_right">
<view class='mink' wx:for="{{list}}" wx:for-index="idx" wx:for-item="itemName" wx:key="*this">
<view class='minl' id='{{idx}}'>{{itemName[0].title}}</view>
<block wx:for="{{itemName}}" wx:key="*this" wx:for-index="idex">
<view class="nav_right_items" wx:if="{{idex>0}}">
<navigator url="../detail/detail" hover-class="other-navigator-hover">
<view>
<image src="{{item.picture}}"></image>
<view >
<text>{{item.desc}}</text>
</view>
</view>
</navigator>
</view>
</block>
</view>
<view style="width:100%;height:30rpx;background:#f0f4f7"></view>
</view>
</scroll-view>
</view>
js代碼:
// pages/list-1/list-1.js
var list = require('../../utils/list.js')
Page({
data: {
// 左側點擊類樣式
curNav: 'A',
scrollTop: 0,
// 定義一個空數(shù)組,用來存放右側滑欄中每一個商品分類的 Height
listHeight:''
},
// 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
onReady: function () {
var that = this;
// 定義右側標題的 rpx 高度 和 px 高度
var right_titleRpxHeight = 60;
var right_titleHeight;
// 定義右側單個商品的 rpx 高度 和 px 高度
var right_contentRpxHeight = 180;
var right_contentHeight;
// 定義左側單個tab的 rpx 高度 和 px 高度
var left_titleRpxHeight = 140;
var left_titleHeight;
// 獲取可視區(qū)屏幕高度
wx.getSystemInfo({
success: function (res) {
// percent 為當前設備1rpx對應的px值
var percent = res.windowWidth / 750;
that.setData({
winHeight: res.windowHeight,
right_titleHeight: Number(right_titleRpxHeight * percent),
right_contentHeight: Number(right_contentRpxHeight * percent),
left_titleHeight: Number(left_titleRpxHeight * percent)
})
}
})
// 把請求到的 list 中的數(shù)據(jù)賦值給 listChild1
var listChild1 = list.List[0];
// 定義一個 names ,用于存放 scroll-into-view 使用的 id
var names = '';
// 循環(huán) listChild1 中的每一項
for (var item in listChild1) {
// 把 listChild1 中每一項的鍵值用“:”(便于后期處理)分隔開,存入 names 中,數(shù)據(jù)格式見圖‘names中的數(shù)據(jù)’
names+= ":"+item;
// 計算右側每一個分類的 Height 。
// listChild1 下的每一個 item 中包含該分類的 title,所以 listChild1[item].length 需要減一
// 右側每一個分類中每一行放兩個商品,所以 this.data.right_contentHeight 除二
// 最后加上 right_titleHeight,此時 height 為右側一個完整分類的高度
var height = (listChild1[item].length - 1) * this.data.right_contentHeight / 2 + this.data.right_titleHeight;
// 同上面 names 的道理,把每一個 height 用“:”隔開放入 listHeight 中
this.data.listHeight += ":" + height;
this.setData({
// 把 listChild1 賦值給 list ,供 wxml 中循環(huán)使用
list: listChild1,
listHeight:this.data.listHeight
})
}
// 把 names 的數(shù)據(jù)切成數(shù)組
var names = names.substring(1).split(':');
this.setData({
names:names
})
},
// 右側滑欄的 bindscroll 事件函數(shù)(ES6寫法)
scroll(event){
// 把 listHeight 切割成數(shù)組
var height = this.data.listHeight.substring(1).split(':');
// 定義一個 index 供左側邊欄聯(lián)動使用
var index = 1;
var num = 0;
for(var i = 0;i<height.length;i++){
// 累計右側滑欄滾動上去的每一個分類的 Height
num+=parseInt(height[i]);
// 循環(huán)判斷 num 是否大于右側滑欄滾動上去的 Height ,然后 get 到 i 值賦給 index
if (num > event.detail.scrollTop){
index = i+1;
// 如果右側滑欄滾動高度小于單個類別高度的 1/2 時,index 為 0
if (event.detail.scrollTop < height[0]/2) {
index = 0;
}
break;
}
}
// 定義并設置左側邊欄的滾動高度
var left_scrollTop = this.data.left_titleHeight*index
this.setData({
scrollTop: left_scrollTop,
// 動態(tài)給左側滑欄傳遞對應該項的 id,用于高亮效果顯示
curNav: this.data.names[index]
})
},
//點擊左側 tab ,右側列表相應位置聯(lián)動 置頂
switchRightTab: function (e) {
var id = e.target.id;
this.setData({
scrollTopId: id,
// 左側點擊類樣式
curNav:id,
})
}
})
樣式表 和 list 數(shù)據(jù)請翻看上一篇:《微信小程序-商品列表左=>右聯(lián)動(一)》
有不懂之處,請先翻閱上一篇,如還有疑問,那肯定是筆者沒寫明白,還請讀者不吝留言!