小程序 通讯录
实例效果:
实现功能:
1.上下滑动通讯录,右侧导航栏与顶部跟随响应
2.点击右侧导航栏,通讯录跳转到响应位置
思路:
1、通讯录内容用scroll-view包住,利用scroll-view提供的bindscroll方法,此方法在滚动时触发(要给scroll-view添加一个默认高度,这个默认高度一般是手机屏幕默认高度,否则可能无法触发方法,因为scroll-view此时视为没有滚动)。方法触发时,能够通过参数获取屏幕实时高度,创建一个数组存储每一组(A、B、C...)的屏幕高度,通过比较控制右侧列表响应。顶部导航栏的实现思路与此基本相同。
2、利用scroll-view提供的scroll-into-view属性,在点击右侧导航栏时,通过变量控制使得通讯录跳转到相应位置
整体实现起来有相当多的细节,例如怎么设置存储屏幕高度的数组,窗体高度如何获取,怎么利用scroll-into-view属性
wxml
<view class="page">
<scroll-view scroll-y="true" bindscroll="scroll" style="height: {{ windowHeight?windowHeight+'px':'' }}" scroll-into-view="{{ toView }}" scroll-with-animation="true">
<view wx:for="{{ addressList }}" wx:for-item="item" wx:for-index="indexType" wx:key="indexType">
<view class="item" id="{{ 'list'+indexType }}">
<view class="type">{{ item.type }}</view>
<block wx:for="{{ item.members }}" wx:for-item="member" wx:for-index="index" wx:key="index">
<view class="member {{ index>0?'border-top-line':'' }}">
<image src="{{ member.img }}" class="img"></image>
<text class="name">{{ member.name }}</text>
</view>
</block>
</view>
</view>
</scroll-view>
<!-- 右侧列表 -->
<view class="list">
<block wx:for="{{ list }}" wx:for-item="item" wx:for-index="index" wx:key="index">
<view class="{{ currentList==index?'current-list':'' }}" bindtap="addressListAnswer" data-index="{{ index }}">
{{ item }}
</view>
</block>
</view>
<!-- 顶部列表 -->
<view class="topbar">
{{ list[currentList] }}
</view>
</view>
wxss
/* pages/addressList/addressList.wxss */
.page {
width: 90%;
margin: 0 auto;
}
.item {
margin: 40rpx 0;
}
.type {
color: #999999;
font-size: 26rpx;
}
.member {
display: flex;
align-items: center;
padding: 15rpx 0;
}
.img {
width: 80rpx;
height: 80rpx;
border-radius: 40rpx;
}
.name {
margin-left: 20rpx;
}
.border-top-line {
border-top: 1px solid #eeeeee;
}
.list {
position: fixed;
top: 40rpx;
right: 14rpx;
font-size: 26rpx;
color: #999999;
}
.current-list {
color: #ff8866;
}
.topbar {
position: fixed;
top: 0;
width: 88%;
color: white;
background-color: #ff8866;
text-align: center;
font-size: 26rpx;
}
js
// pages/addressList/addressList.js
Page({
/**
* 页面的初始数据
*/
data: {
// 列表数据层
addressList: [{
type: 'A',
members: [{
img: '/images/1.jpg',
name: 'Amy',
},
{
img: '/images/2.jpg',
name: 'Amy',
},
{
img: '/images/3.jpg',
name: 'Amy',
},
]
},
{
type: 'B',
members: [{
img: '/images/1.jpg',
name: 'Bili',
},
{
img: '/images/2.jpg',
name: 'Bili',
},
{
img: '/images/3.jpg',
name: 'Bili',
},
{
img: '/images/4.jpg',
name: 'Bili',
},
{
img: '/images/5.jpg',
name: 'Bili',
}
]
},
{
type: 'C',
members: [{
img: '/images/1.jpg',
name: 'Cat',
},
{
img: '/images/2.jpg',
name: 'Cat',
},
{
img: '/images/3.jpg',
name: 'Cat',
},
{
img: '/images/4.jpg',
name: 'Cat',
},
{
img: '/images/5.jpg',
name: 'Cat',
}
]
},
{
type: 'D',
members: [{
img: '/images/1.jpg',
name: 'Dave',
},
{
img: '/images/2.jpg',
name: 'Dave',
},
{
img: '/images/3.jpg',
name: 'Dave',
},
{
img: '/images/4.jpg',
name: 'Dave',
},
{
img: '/images/5.jpg',
name: 'Dave',
}
]
},
{
type: 'O',
members: [{
img: '/images/1.jpg',
name: 'Olive',
},
{
img: '/images/2.jpg',
name: 'Olive',
},
{
img: '/images/3.jpg',
name: 'Olive',
},
{
img: '/images/4.jpg',
name: 'Olive',
},
{
img: '/images/5.jpg',
name: 'Olive',
}
]
},
{
type: 'P',
members: [{
img: '/images/1.jpg',
name: 'Panda',
},
{
img: '/images/2.jpg',
name: 'Panda',
},
{
img: '/images/3.jpg',
name: 'Panda',
},
{
img: '/images/4.jpg',
name: 'Panda',
},
{
img: '/images/5.jpg',
name: 'Panda',
}
]
},
{
type: 'R',
members: [{
img: '/images/1.jpg',
name: 'Rabbit',
},
{
img: '/images/2.jpg',
name: 'Rabbit',
},
{
img: '/images/3.jpg',
name: 'Rabbit',
},
{
img: '/images/4.jpg',
name: 'Rabbit',
},
{
img: '/images/5.jpg',
name: 'Rabbit',
}
]
},
{
type: 'T',
members: [{
img: '/images/1.jpg',
name: 'Tom',
},
{
img: '/images/2.jpg',
name: 'Tom',
},
{
img: '/images/3.jpg',
name: 'Tom',
},
{
img: '/images/4.jpg',
name: 'Tom',
},
{
img: '/images/5.jpg',
name: 'Tom',
}
]
},
],
// 每个类型在页面中的高度
addressListHeight: [],
// 右侧列表内容
list: [],
// 窗体默认高度
windowHeight: 0,
// 右侧列表响应控制
currentList: 0,
// 控制变量:点击右侧列表通讯录响应
toView: '',
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.setNavigationBarTitle({
title: '通讯录',
});
// 获取窗体高度
wx.getSystemInfo({
success: (result) => {
this.setData({
windowHeight: result.windowHeight
})
},
})
this.getRightList();
this.getTypeHeight();
},
// 获取类型高度
getTypeHeight: function (e) {
let typeHeight = [];
wx.createSelectorQuery().selectAll('.type').boundingClientRect((rects) => {
rects.forEach((item, index) => {
typeHeight.push(item.top);
})
}).exec();
this.setData({
addressListHeight: typeHeight
});
},
// 根据通讯录数据动态生成右侧列表
getRightList: function (e) {
let list = [];
this.data.addressList.forEach((item, index) => {
list.push(item.type);
});
this.setData({
list: list
});
},
// 通讯录滚动时触发,右侧列表响应
scroll: function (e) {
this.answer(e.detail.scrollTop);
},
// 右侧列表响应方法
answer: function (currentHeight) {
let addressListHeight = this.data.addressListHeight;
for(let i = 1, len = addressListHeight.length; i < len; i++) {
if (currentHeight >= addressListHeight[i-1] && currentHeight < addressListHeight[i]) {
this.setData({
currentList: i-1
});
break;
}
}
},
// 点击右侧列表,通讯录响应方法
addressListAnswer: function (event) {
console.log(event);
let index = event.currentTarget.dataset.index;
this.setData({
toView: 'list'+index
})
}
})
再附上一个GitHub链接吧:通讯录