滚动吸顶效果

469 阅读3分钟

概述

在平常浏览电商网站中,经常会看到一些tab栏滚动吸顶,正好项目有需求需要实现滚动吸顶效果,所以就动手去实现了滚动吸顶

position:sticky 实现吸顶

效果图

20230322_203258.gif

1. 粘性定位是什么?

粘性定位 sticky 相当于相对定位 relative 和固定定位 fixed 的结合;在页面元素滚动过程中,某个元素距离其父元素的距离达到 sticky 粘性定位的要求时;元素的相对定位 relative 效果变成固定定位 fixed 的效果。

2. 如何去使用?

使用条件

  1. 父元素不能设置overflow:hidden 或者 overflow:auto属性
  2. 必须指定top、bottom、left、right属性中一个,否则只会相对定位
  3. 父元素高度不能低于sticky元素高度
  4. sticky元素仅在父元素下生效

这个属性好用吗?

image.png 这个属性兼容性不是很好,在ios系统下兼容性比较好,安卓下需要考虑使用offsetTop计算

使用 obj.getBoundingClientRect().top 实现

实现思路:监听scroll事件,判断当前页面的滚动位置,当滚动距离大于导航条距顶部的距离时,为导航条采用窗口定位

 <div class="wrap">
      <div>H5-血糖</div>
      <div class="title">css吸顶效果实现</div>
      <div class="nav" id="nav">
        <li>HTM5学堂</li>
        <li>HTM5微博</li>
        <li>HTM5学堂</li>
        <li>HTM5微博</li>
      </div>
      <ul class="item">
        <li class="item-list">我的吸顶111</li>
        <li class="item-list">我的吸顶222</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
        <li class="item-list">海上生明月天涯若比邻</li>
      </ul>
    </div>
    <script>
      const nav = document.getElementById("nav");
      // 获取页面中导航条相对浏览器视窗的位置
      const rect = nav.getBoundingClientRect();
      let insetDiv = document.createElement("div");
      nav.parentNode.replaceChild(insetDiv, nav);
      insetDiv.appendChild(nav);
      insetDiv.style.height = rect.height + "px";
      // 获取导航条距页面顶部距离
      let navTop = nav.offsetTop;
      document.onscroll = function () {
        const btop =
          document.body.scrollTop || document.documentElement.scrollTop;
        if (btop  > navTop) {
          nav.className = "clearfix fix";
        } else {
          nav.className = "clearfix";
        }
      };

      const btn = document.getElementById("btn");
      btn.onclick = function () {
        window.scrollTo({
          top: 0,
        });
      };
    </script>

遇到的问题

吸顶的那一刻伴随抖动

原因:吸顶元素position变成fixed的时候,该元素脱离了文档流,下一个元素就进下了补位。就是补位造成了抖动

解决方案:为这个吸顶元素添加一个等高的父元素

吸顶效果不能及时响应

描述:

当页面往下滚动时,吸顶元素需要等页面滚动停止之后才会出现吸顶效果

当页面往上滚动时。滚动到吸顶元素恢复文档流位置时吸顶元素不恢复原样,而等页面停止滚动才会恢复原样

原因: 在ios系统上不能实时监听scroll滚动监听时间,在滚动停止时才触发其相关事件。

解决方案: IOS使用 position:sticky,安卓滚动监听getBoundingClientRect().top的值。如果IOS版本过低呢?可以使用 window.requestAnimationFrame()