vue实现电梯锚点导航

1、目标效果

        最近喝了不少的咖啡、奶茶,有一个效果我倒是挺好奇怎么实现的:

        (1)点击左侧分类菜单,右侧滚动到该分类区域

        (2)右侧滑动屏幕,左侧显示当前所处的分类区域

vue实现电梯锚点导航_第1张图片

        这种功能会出现在商城项目中或者分类数量较多的项目中,专业名称称电梯导航 

        目标效果:

        (1)点击左侧的分类,右侧滑动到指定区域

vue实现电梯锚点导航_第2张图片

       

        (2)滚动右侧区域,左边分类显示当前所处的分类区域

vue实现电梯锚点导航_第3张图片

2、原理

(1)这要用到原生js关于偏移量和位置相关的api,这些api建立在你的布局是定位的基础上,父亲相对定位左边分类和右边商品都是绝对定位

(2)左边分类要与右侧商品模块数量一一相等(数量和位置都要对应相等),否则实现不了电梯导航效果

(3)点击左侧分类,右侧跳转到对应模块;这用到了window.scrollTo(水平方向距离,竖直方向距离)  

(4)右侧滑动,左侧发生相应的变化,这要用到滚动事件,vue中使用滚动事件需要再onMounted()生命周期注册一下滚动事件

onMounted(() => {
    window.addEventListener('scroll', handleScroll);
})

(5)如何判断滚动到什么程度左侧才显示对应的模块?

  • dom.offsetTop:每个dom元素有该属性,表示距离顶部窗口的距离

  • document.documentElement.scrollTop:表示页面滚动的距离

  • document.documentElement.scrollTop >= dom.offsetTop:显示对应的模块,可以通过遍历商品模块数组,拿到对应的索引,然后设置左边分类对应的dom为激活状态

(6) 出现一个问题:window.scrollTo()将模块滚动至某一位置  与页面滚动事件 发生了冲突,此时可以添加一个互斥变量isLock,等window.scrollTo()滚动结束之后,再放开锁

    // 获取选中的dom元素
    const typeItemDom = shop.value[val]

    // 开锁
    isLock.value = true

    // 第一个参数为水平方向,第二个参数为纵轴方向
    window.scrollTo(0, typeItemDom.offsetTop)

    setTimeout(() => {
        //关锁
        isLock.value = false
    }, 0)

(7)为什么放开锁要在setTimeout里面?根据js事件循环机制,同步任务(主线程代码、new Promise里面的代码)执行速度快于异步任务(setTimeout、setInterval、ajax、promise.then里面的任务 )这样才能确保锁是在 window.scrollTo() 执行完毕之后才打开的

3、源代码

        App.vue






        ClassifyByVue.vue





你可能感兴趣的:(前端,vue.js,前端,javascript)