实现一个字母索引列表

2,445 阅读2分钟
原文链接: aaronxue.top

实现一个字母索引列表

 Vue |  2017年12月20日 |

  • 实际项目开发中经常会遇到这样的需求,比如:城市列表、联系人列表等等,但是大部分Vue、React组件库都没有提供这种组件,无奈之下只能自己动手实现了
  • Demo演示

列表的实现需要主要实现两个需求

  1. 滑动列表,右侧字母索引同步变化
    • 根据列表滚动的距离如果大于Group头部h2距离页面顶部的位置(可以自己根据需求设置距离),然后可以获得当前的h2的index或其他什么标记但必须与右侧索引一一对应,右侧字母索引根据标记更新状态
  2. 点击右侧索引,列表自动滚动到指定位置
    • 点击右侧字母获取一个标记,比如index,列表根据标记滚动到指定h2所在的位置

实现过程

  1. 准备工作:引入一些库,为了开发方便
    • jQuery这个不用说了,实在好用
    • betterscroll这个库做移动端滚动页面,真的叼,后面会说明用这个库真的会少些很多逻辑
  2. 先实现需求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的位置),同步右侧索引
  3. 实现需求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");
        });
        
  4. 大功告成,大家可以直接看效果
    • 小伙伴们如果有更好的方案,请分享一下,互相学习

HTML JavaScript Vue Web component