实现一个字母索引列表
Vue | 2017年12月20日 |
- 实际项目开发中经常会遇到这样的需求,比如:城市列表、联系人列表等等,但是大部分Vue、React组件库都没有提供这种组件,无奈之下只能自己动手实现了
- Demo演示
列表的实现需要主要实现两个需求
- 滑动列表,右侧字母索引同步变化
- 根据列表滚动的距离如果大于Group头部h2距离页面顶部的位置(可以自己根据需求设置距离),然后可以获得当前的h2的index或其他什么标记但必须与右侧索引一一对应,右侧字母索引根据标记更新状态
- 点击右侧索引,列表自动滚动到指定位置
- 点击右侧字母获取一个标记,比如index,列表根据标记滚动到指定h2所在的位置
实现过程
- 准备工作:引入一些库,为了开发方便
- jQuery这个不用说了,实在好用
- betterscroll这个库做移动端滚动页面,真的叼,后面会说明用这个库真的会少些很多逻辑
- 先实现需求1
- 在scroll事件里实现回调,更新字母索引
scroll.on('scroll', function (pos) { var scrollTop = $(document).scrollTop(); var contentItems = $("#content").find(".item"); var currentItem = ""; contentItems.each(function () { var contentItem = $(this); var offsetTop = contentItem.offset().top; if (scrollTop > offsetTop - 200) { currentItem = "#" + contentItem.attr("id"); } }); if (currentItem != $("#menu").find(".current").attr("name")) { $("#menu").find(".current").removeClass("current"); $("#menu").find("span[name='" + currentItem + "']").addClass("current"); } }); - 循环获得的所有h2,如果 滚动距离 > h2距离页面顶部-200的位置(也就是h2距离视口200的位置),同步右侧索引
- 在scroll事件里实现回调,更新字母索引
- 实现需求2
- 这里讲下没有用betterscroll的情况,真的不好写,大概逻辑是:
- 获得标记同步列表,这个都一样
- 列表循环标记之前的所有Group,累加他们的高度也就是contentItem.offset().top,如果直接通过contentItem.offset().top获取会出问题,因为我们要拿的必须是初始化时的contentItem.offset().top
- 最后就是是列表滚动到指定的contentItem.offset().top
$(".l-cell").delegate("span","click", function () { var allHeight = 0; var index = $(".l-cell span").index($(this)); for (let i = 0; i < index; i++) { allHeight+=$(".brand-list .item").eq(i).height() } console.log(allHeight); that.$refs.scroller.reset({ top:allHeight }); $(this).siblings().removeClass("current").end().addClass("current"); });
- 接下来就是用betterscroll实现,不要太简单!!!
- 它有个scrollToElement方法,直接写滚动就可以了
$(".l-cell").delegate("span", "click", function () { var allHeight = 0; var index = $(".l-cell span").index($(this)); scroll.scrollToElement( $(".brand-list .item").eq(index)[0], '300'); $(this).siblings().removeClass("current").end().addClass("current"); });
- 它有个scrollToElement方法,直接写滚动就可以了
- 这里讲下没有用betterscroll的情况,真的不好写,大概逻辑是:
- 大功告成,大家可以直接看效果
- 小伙伴们如果有更好的方案,请分享一下,互相学习