如何做出无缝的导航栏滚动贴边效果?有动图说明

先放图,目前效果:
图片描述

我是通过判断导航栏距离顶部的大小来给它一个position:fiexd;,但是现在的问题主要就是不能无缝的衔接起来。
因为代码进行判断的时候,导航栏的移动距离已很大了。

比如我是判断距离在0~10像素间的时候定位到浏览器顶部,但是实际上通过touchmove,在滑动的时候对导航栏位置的取值频率太低了,有可能已经划过了30px才取一次,这样的话不能精确控制它的位置。
请问有什么更好的办法吗?

最难的一点就是:无法通过scrollTop获取页面滚动的距离,我是通过getBoundingClientRect().top来获取元素距离顶部的位置。但是不能精确/高频率的获取值

更新
用的vue.js

// 组件
<template>
    <! -- 滚动的部分,父级组件高度固定,设置overflow:scroll; -->
  <div class="wrapper" ref="page">
    <!--head-->
    <p-header></p-header>
    <!--nav 需要贴边的导航栏 -->
    <div class="out-wrapper" ref="navbarWrap">
      <div class="tabbar-wrapper" ref="navbar">
        <router-link class="tabbar-btn" to="/home_page/article">
          <span>探文</span>
          <div class="line"></div>
        </router-link>
        <router-link class="tabbar-btn" to="/home_page/shop">
          <span>店铺</span>
          <div class="line"></div>
        </router-link>
        <router-link class="tabbar-btn" to="/home_page/album">
          <span>相册</span>
          <div class="line"></div>
        </router-link>
      </div>
    </div>
    <!--list-->
    <transition>
      <keep-alive>
        <router-view></router-view>
      </keep-alive>
    </transition>

  </div>
</template>

js部分



mounted() {
    // page:滚动的页面,navbar:导航栏,
      // navWrap:用来给nav占位的元素,
      // navLoc:保存页面加载后导航栏距离顶部的位置
    
      let page = this.$refs.page;
      let navbar = this.$refs.navbar;
      let navWrap = this.$refs.navbarWrap;
      let navLoc = navWrap.getBoundingClientRect().top;
      let self = this;
    
      page.onscroll=function (event) {
        console.log('scroll')  // 没有触发
      }
      page.addEventListener('scroll',function (event) {
        console.log('croll')  // 没有触发
        let _navWrapTop = navWrap.getBoundingClientRect().top;
        console.log('navWrap',_navWrapTop)
      })
      window.addEventListener('scroll',function () {
        console.log('window')  // 没有打印
      })
      
      page.addEventListener('touchmove', function (event) {
        let moveLoc = page.getBoundingClientRect().top

        // 逻辑判断 往上还是往下
        if (moveLoc - self.startLoc > 0) {
          // 往下
          console.log('down');
          let _navWrapTop = navWrap.getBoundingClientRect().top;
          console.log('nav距离顶部',_navWrapTop)
          if(_navWrapTop>=0){
            console.log('满足条件')
            navbar.style.position = 'relative';

            self.count =0
          }else {
            console.log('nonono')
          }

        } else if (moveLoc - self.startLoc < 0) {
          // 向上
          console.log('up')
          // 方案2
          if (navbar.getBoundingClientRect().top <= 10) {
            if(self.count ==0){
              navbar.style.position = 'fixed';
              navbar.style.top = '0';
              navbar.style.zIndex = '999';
              self.count +=1;
            }
          }
      }
    })
}
阅读 5.5k
4 个回答

应该是判断scrollTop > 本身导航离顶部距离 就设置浮动吧.

优先使用 position: sticky; 属性。
判断一下,对低版本使用 js 。

通常的经验是,写一个一样的给隐藏,在你导航栏滑倒一半左右位置时出现,因为你直接操作会产生回流,性能损耗比较大。

其实不需要取导航的动态值,只需要取整个$(document).scrollTop()值>上方黑色展示区域height
然后show()或者fixed
因为导航上面黑色背景信息展示区域的height是固定的

clipboard.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题