案例:通讯录
list.wxml
<view class="list_wrap"> <scroll-view class="list_scroll" scroll-with-animation bindscroll="handleScroll" scroll-y scroll-into-view="{{currentKey}}"> <!-- 汽车首写字母 --> <view wx:for="{{list}}" wx:key="{{index}}" class="list_title" id="{{item.key}}" > <text class="bscroll_title">{{item.key}}</text> <!-- 汽车名字 --> <view wx:for="{{item.row}}" wx:key="{{index}}" wx:for-item="conItem" wx:for-index="i" class="listcon_box" > <view class="image"><image src="{{conItem.img}}"/></view> <text class="list_con">{{conItem.name}}</text> </view> </view> <view class="bb"></view> </scroll-view > <!-- 导航列表 --> <view class="navList"> <view wx:for="{{list}}" wx:key="{{index}}" bindtap="handleNav" data-key="{{item.key}}" >
//判断如果滑动的下标==导航列表的下标?'active':'' <text class="{{currentIndex==index?'active':''}}">{{item.key}}</text> </view> </view> </view>
list.wxss
page{height: 100%;background: #eee;} //必须设置高度为100% .list_wrap{height: 100%} //必须设置高度100% .list_scroll{height: 100%} //必须设置高度100%
.listcon_box{ 100%;height: 50px;background: #fff;display: flex;border-bottom: solid 1px #eee;} .bscroll_title{padding-left: 10px;height: 40px;} .image{flex: 1;display: flex;justify-content: center;align-items: center;} .image image{ 30px;height:30px;} .list_con{flex: 9;padding-left: 10px;display: flex;align-items: center;} .active{color: cornflowerblue;} .bb{height: 100%;} .navList{position: fixed;height: 100%;top:20px;right: 15px;}
list.js
// pages/list/list.js Page({ /** * 页面的初始数据 */ data: { // 全部数据 list:[], // 每天滚动列表的高度 listItemTops:[], // 添加高亮 currentIndex:0, // 点击nav currentKey:"A" }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { wx.request({ url: 'https://www.easy-mock.com/mock/5ceb8bac32cfe337f96fe748/example/car', success:(res)=>{ console.log(res.data.data.items) this.setData({ list:res.data.data.items },()=>{ const query=wx.createSelectorQuery(); query.selectAll('.list_title').boundingClientRect((res) => { // console.log(res)//可以获取到每条列表高度 this.setData({ listItemTops: res.map(item => item.top) }) }).exec() }) } }) }, // 列表滚动事件 handleScroll(e){ // console.log(e) let scrollTop = e.detail.scrollTop; let {listItemTops}=this.data
//为了给导航栏添加样式
//循环每个列表距离顶部的距离 for (var i = 0; i < listItemTops.length-1;i++){
//判断滚动页面的距离>=对应列表距离顶部的距离 if(scrollTop>=listItemTops[i]){ this.setData({ currentIndex:i }) } } }, // 点击导航nav事件 handleNav(e){ console.log(e) let { key } = e.currentTarget.dataset
//设置这个currentKey是为了在页面scroll-into-view添加,只有加了这个点击导航时才会动 this.setData({ currentKey:key }) }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })