公司项目要做一个类似微信通讯录导航的效果,点击右侧字母页面滚动到相应位置。因为微信小程序没有dom概念,所以不能使用锚点,也不能直接获取对应字母相对页面的偏移位置。此时只能使用小程序创建对象实例的API获取节点信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | let query = wx.createSelectorQuery(). in ( this ); query.selectViewport().scrollOffset() query.select( "#Nav" ).boundingClientRect(); query.select( "#FilterNav" ).boundingClientRect(); query.select( "#" +((letter== '#' )? 'other' :letter)).boundingClientRect(); query.exec( function (res) { let scrollTop = 0; if (res[3]){ scrollTop = res[0].scrollTop + res[3].top } else { scrollTop = res[0].scrollTop; } wx.pageScrollTo({ scrollTop: scrollTop - res[1].height - res[2].height, duration: 300 }); }); |
1.先创建节点对象,wx.createSelectorQuery()返回一个对象实例;
2.选择显示区域;
3.调用select方法,传入节点的id值,可在同一节点对象进行多次调用,最后会返回数组结果(上图中滚动区域距离页面顶部是有两个导航栏高度的距离的,所以查询了两次导航栏);
4.exec()回调方法中可以获取所查询所有节点的信息,数组第一条为页面的位置信息(滚动距离),获取到对应字母节点的top值为节点相对于屏幕顶部的位置
结果:页面滚动位置 = 页面滚动距离 + 字母节点相对屏幕高度距离 - 头部导航条高度 - 菜单栏高度
wx.pageScrollTo()调用API页面滚动
如果是让滚动容器滚动到指定位置,计算位置会有一点不同:

1 2 3 4 5 6 7 8 9 | var query = wx.createSelectorQuery(). in ( this ); query.select( "#swiper" ).boundingClientRect(); query.select( "#" + letter).fields({ rect: true ,scrollOffset: true }); query.selectViewport().scrollOffset() query.exec((res)=>{ _this.setData({ letterScrolltop: res[1].top - res[0].top }) }); |