微信和通訊錄經(jīng)??吹竭@種,那么在小程序如何實(shí)現(xiàn)呢(等下我們需要用到小程序的一個(gè)官方組件),這個(gè)功能可以拆分兩塊,一個(gè)是滾動區(qū)域,一個(gè)是滑動定位區(qū)域。
小程序里面實(shí)現(xiàn)滾動到指定位置,可以用 scroll-view 組件. (點(diǎn)擊我即可查看小程序文檔)
<scroll-view class="goup_list" scroll-with-animation="true" scroll-y="true" style="height: 300rpx;" scroll-into-view="{{toView}}">
<具體業(yè)務(wù)界面代碼 />
</scroll-view>
復(fù)制代碼
最后面是我剛剛錄gif的代碼??梢钥吹?nbsp;scroll-view
組件,有一個(gè)屬性 scroll-into-view
,這個(gè)屬性可以實(shí)現(xiàn)轉(zhuǎn)跳到指定位置。值是id,也就是Gif看到的 B、C、D的ID。
(最后會有完整代碼)
滑動我們會想到 touchmove
事件,我們需要依靠這個(gè)判斷滑動到了哪個(gè)索引(字母)。
但是滑動里面沒有直接告訴你,是哪個(gè)組件,所以我們需要根據(jù)現(xiàn)有的信息進(jìn)行利用,這里用的是y,x的信息。
拿到x,y之后的邏輯如下
用文字不好描述清楚,看下面圖,可以這樣求偏差值,然后除以每項(xiàng)的高度,就拿到了滑動到了第幾項(xiàng)。 這里又涉及一個(gè)問題就是,怎么求單個(gè)項(xiàng)的高度。 height / 個(gè)數(shù)。
var y = e.touches[0].pageY;
var itemLen = this.data.list.length
var height = letterDomRes.height
var top = letterDomRes.top
// 滑動的偏移量(偏差值)
var offsetTop = (height + top - y)
var itemHeight = height / itemLen
var index = itemLen - ((offsetTop / itemHeight)|0) - 1
if(index < 0 || index >= itemLen){
return
}
復(fù)制代碼
還有就是上面數(shù)據(jù)從哪里來,也就是小程序如何拿下圖中的top值和height。
//創(chuàng)建節(jié)點(diǎn)選擇器
var query = wx.createSelectorQuery()
query.select('.letter-index').boundingClientRect()
query.exec(function (res) {
letterDomRes = res[0]
console.log(letterDomRes);
})
復(fù)制代碼
letterDomRes.height
letterDomRes.top
就是我們需要的數(shù)據(jù)了。
到這里就都完成了。然后加一個(gè)優(yōu)化,超出滑動范圍就return,上面代碼也有了,然后設(shè)置的時(shí)候判斷是否在滑動期間,是的話過濾相同的設(shè)置。
// pages/word/strange.js
var letterDomRes = {}
var moveing_word = ''
Page({
/**
* 頁面的初始數(shù)據(jù)
*/
data: {
toView: '',
list: [
{
word: 'B',
children: [
{word: 'Ban', translation: 'vt. 禁止,查禁;n. 禁止,禁令'},
{word: 'Ban', translation: 'vt. 禁止,查禁;n. 禁止,禁令'},
{word: 'Ban', translation: 'vt. 禁止,查禁;n. 禁止,禁令'},
]
},
{
word: 'C',
children: [
{word: 'Ban', translation: 'vt. 禁止,查禁;n. 禁止,禁令'},
{word: 'Ban', translation: 'vt. 禁止,查禁;n. 禁止,禁令'},
{word: 'Ban', translation: 'vt. 禁止,查禁;n. 禁止,禁令'},
]
},
{
word: 'D',
children: [
{word: 'Ban', translation: 'vt. 禁止,查禁;n. 禁止,禁令'},
{word: 'Ban', translation: 'vt. 禁止,查禁;n. 禁止,禁令'},
{word: 'Ban', translation: 'vt. 禁止,查禁;n. 禁止,禁令'},
]
},
]
},
// ---- methods
letterTap(e){
var id = e.target.id
// console.log(id)
this.setListSite(id)
},
letterMove(e){
var y = e.touches[0].pageY;
var itemLen = this.data.list.length
var height = letterDomRes.height
var top = letterDomRes.top
// 滑動的偏移量(偏差值)
var offsetTop = (height + top - y)
var itemHeight = height / itemLen
var index = itemLen - ((offsetTop / itemHeight)|0) - 1
if(index < 0 || index >= itemLen){
return
}
var letter = this.data.list[index].word
// console.log(index, letter)
// [優(yōu)化] 過濾相同的
if(moveing_word == letter){
return
}
moveing_word = letter
this.setListSite('word_' + letter)
// console.log(height / this.data.list.length)
// / this.data.list.length
// console.log(letterDomRes.top)
},
letterEnd(e){
// 重置
moveing_word = ''
},
/**
* 設(shè)置滾動位置
* @param {String} id 前綴 + 字母
*/
setListSite(id){
wx.showToast({
title: id.split('_')[1],
icon: 'none',
})
this.setData({
toView: id,
duration: 500,
})
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面加載
*/
onLoad: function (options) {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
*/
onReady: function () {
//onshow中獲取索引條高度
var query = wx.createSelectorQuery();//創(chuàng)建節(jié)點(diǎn)選擇器
query.select('.letter-index').boundingClientRect()
query.exec(function (res) {
//res就是 所有標(biāo)簽為mjltest的元素的信息 的數(shù)組
letterDomRes = res[0]
console.log(letterDomRes);
//取高度
console.log("height : "+res[0].height);
})
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面顯示
*/
onShow: function () {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面隱藏
*/
onHide: function () {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面卸載
*/
onUnload: function () {
},
/**
* 頁面相關(guān)事件處理函數(shù)--監(jiān)聽用戶下拉動作
*/
onPullDownRefresh: function () {
},
/**
* 頁面上拉觸底事件的處理函數(shù)
*/
onReachBottom: function () {
},
})
復(fù)制代碼
<!--pages/word/strange.wxml-->
<view class="container">
<scroll-view class="goup_list" scroll-with-animation="true" scroll-y="true" style="height: 300rpx;" scroll-into-view="{{toView}}">
<view class="">
<view class="group_item" wx:for="{{list}}" wx:key="{{index}}">
<view class="group">
<view class="title" id="word_{{item.word}}">{{item.word}}</view>
<view class="word_list">
<view class="word_list_item" wx:for="{{item.children}}" wx:key="{{index}}">
<view class="e">
<view>{{item.word}}</view>
<view class="">{{item.translation}}</view>
</view>
<image mode="widthFix" src="/image/right.png" class="right-image" />
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<view class="letter-index" bind:touchmove="letterMove" bindtap="letterTap" bind:touchend="letterEnd">
<view class="item" id="word_{{item.word}}" wx:for="{{list}}" wx:key="index">{{item.word}}</view>
</view>
</view>
復(fù)制代碼
工作日 8:30-12:00 14:30-18:00
周六及部分節(jié)假日提供值班服務(wù)