如题,实现下图的导航效果。
    02导航演示.gif

    方案1
    1、实现滚动时导航栏active项目变化
    监听scroll事件,通过每个模块的高度、scroll的距离,计算出当前active的模块,把导航栏对应的标题置为active的状态。这种方案不使用锚点,不需要管理路由状态。
    2、点击导航栏,页面滚动到导航位置。(导航栏active状态跟随变化,无需额外实现)
    点击导航栏后,计算当前选中的元素到页面顶部的距离。通过控制滚动距离,将制定的导航栏显示在窗口顶端。

    要点:
    1、scroll事件最好加上防抖,减轻性能压力。
    2、对高度固定(每个模块的高度都固定)的页面更容易实现。
    3、实现的时候要注意向上滚动的时候,滚动数值是一个负值。
    4、这个方案不需要控制路由,也不需要对页面的元素打上锚点。
    5、初始化高度遍历,如果有异步加载的区域,一定要在异步加载后再遍历获取高度。

    方案2
    H5特性 IntersectionObserver

    创建IntersectionObserver实例(容器)
    调用实例的observe()方法,监听每一个需要导航的元素。

    1、实现滚动时导航栏active项目变化,同时变更路由
    在容器观察到内部元素出界的时候,变更导航栏的active标题,同时变更路由状态。

    2、点击导航栏,页面滚动到导航位置。
    通过锚点实现。

    要点:
    1、处理被观察元素从上部下部出界的情况。
    2、处理一个容器内有多个被观察元素的情况下,导航栏active的逻辑。

    看到浏览器location里有#,大概率是用了IntersectionObserver。要是使用遍历每个模块高度的情况下还用锚点做跳转,那属实有点笨拙。