一個完整的字母導航欄功能包括三個部分,可按需食用:
1.點擊跳轉(zhuǎn)
2.滑動更新
3.保存選中
一蠢络、點擊跳轉(zhuǎn)功能
主要思路是利用微信自帶的<scroll-view>組件的scroll-into-view屬性卡睦,非常方便筒主。
1.在需要進行跳轉(zhuǎn)的scroll-view組件上綁定scroll-into-view屬性
2.綁定的屬性值必須為動態(tài)值有额,與跳轉(zhuǎn)目標的id對應(yīng)效诅,如:{{toView}}
3.設(shè)置跳轉(zhuǎn)目標所在元素的id進行定位(關(guān)鍵N喑恕!)
示例代碼如下:
<scroll-view scroll-into-view="{{toView}}">
<view id="{{ item.firstChar }}">{{ item.firstChar }}</view>
</scroll-view>
4.在字母導航列表上綁定事件和自定義屬性data-xxxx稼虎,以便事件的捕獲currentTarget.dataset
示例代碼如下:
<view wx:for="{{sortedCityList}}"
data-first-char="{{item.firstChar}}"
bindtap="handleToView"
>
{{item.firstChar}}
</view>
5.在js文件中定義toView變量和handleToView事件
示例代碼如下:
data: {
toView: "A", // 用戶點擊的字母id
},
handleToView: function (event) {
let view = event.currentTarget.dataset.firstChar
this.setData({
toView: view
})
}
但是衅檀!這里還有個小問題
那就是,如果將對應(yīng)的跳轉(zhuǎn)元素設(shè)置了:position: sticky屬性霎俩,從上往下點擊時能正常跳轉(zhuǎn)哀军,但從下往上點擊時,會出現(xiàn)跳轉(zhuǎn)不到期望位置的情況打却,這個問題有待解決杉适。
二、滑動更新
滑動頁面時同步更新導航欄的選中樣式柳击,實現(xiàn)的主要思路是猿推,首先使用wx.createSelectorQuery()獲取每個字母標題對應(yīng)的高度以及對應(yīng)的字母id,然后使用scroll-view組件的bindScroll監(jiān)聽當前頁面的高度進行比較并賦值
示例代碼如下:
// 獲取每個字母標題對應(yīng)的高度及對應(yīng)字母id,并存儲起來捌肴,第二次進入頁面時判斷蹬叭,不能重復計算
if (heightArray.length === 0) {
let that = this
setTimeout( function () {
const query = wx.createSelectorQuery()
query.selectAll('.first-character').boundingClientRect( function (rect) {
rect.forEach( function (value) {
heightArray.push({ 'height': value.top , 'letter': value.id })
})
that.setData({
heightArray
})
app.store.heightArray = heightArray
}).exec()
},1)
}
得到heightArray后,通過bindScroll事件綁定觸發(fā)方法状知,在滾動時進行判斷:
letterScroll (event) {
//如果實時判斷影響性能的話秽五,可以用清除定時器的方法節(jié)流
// clearTimeout(this.data.timeId)
this.data.timeId = setTimeout( () => {
let currentScrollTop = event.detail.scrollTop // 滾動條距離頂部的實時距離
const heightArray = this.data.heightArray
for (let i = 0; i <= heightArray.length; i++) {
// 判斷是否滑到最后一個字母
if (currentScrollTop >= heightArray[heightArray.length-1].height) {
this.setData({
currentLetter: heightArray[heightArray.length-1].letter
})
// console.log('currentScrollTop',currentScrollTop)
// console.log(heightArray)
// console.log('end:',this.data.currentLetter)
break
}else if (currentScrollTop < heightArray[i+1].height) {
this.setData({
currentLetter: heightArray[i].letter
})
// console.log('currentScrollTop',currentScrollTop)
// console.log('currentScroll',this.data.currentLetter)
break
}
}
},200)
}
三、保存選中
主要思路是將狀態(tài)變量存到app的data中饥悴,初始化時從app data讀取并賦值坦喘。