吸顶效果

107 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 27 天,点击查看活动详情

postion sticky

粘性定位

粘性定位可以被认为是相对定位(position: relative)和固定定位(position: fixed)的混合。元素在跨越特定阈值前为相对定位,之后为固定定位

  #xx {
    position: sticky;
    background: rgb(87, 79, 206);
    top: 0px
  }

id为xx的元素 滚动到距离视口 top 距离小于 0px 之前,元素为相对定位。之后,元素将固定在与顶部距离 0px 的位置,直到视口回滚到阈值以下。

元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block(最近块级祖先 nearest block-level ancestor)

image.png 视口元素:显示内容的区域。会设置宽,高。一般是。
容器元素:离 sticky 元素最近的能滚动的祖先元素。
粘性约束元素:粘性定位的父元素。有时,也会出现粘性约束元素就是容器元素的情况。
sticky 元素:设置了 position: sticky; 的元素。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<style>
  * {
    padding: 0;
    margin: 0;
  }


  .content div:nth-child(odd) {
    background-color: #09f;
  }
  .content div{
    height: 200px;
    text-align: center;
  }



  #xx {
    position: sticky;
    background: rgb(87, 79, 206);
    top: 10px
  }

  #oo {
    position: sticky;
    background: rgb(190, 31, 31);
    top: 10px
  }
</style>

<body>
  <div class="container">
    <div class="content">
      <div id="xx">A</div>
      <div>AAAAAAA</div>
      <div>AAAAAAA</div>
      <div>AAAAAAA</div>
      <div>AAAAAAA</div>
      <div>AAAAAAA</div>
      <div>AAAAAAA</div>
      <div>AAAAAAA</div>
      <div>AAAAAAA</div>
 
    </div>
    <div class="content">
      <div id="oo">B</div>
      <div>BBBBBBB</div>
      <div>BBBBBBB</div>
      <div>BBBBBBB</div>
      <div>BBBBBBB</div>
      <div>BBBBBBB</div>
      <div>BBBBBBB</div>
      <div>BBBBBBB</div>
      <div>BBBBBBB</div>
      <div>BBBBBBB</div>
      <div>BBBBBBB</div>
  
    </div>
  </div>

</body>
<script>

</script>

</html>

吸顶自从有这个样式就容易实现了,但是怎么能给吸顶后的dom加一点骚气侧漏的样式呢?

requestAnimationFrame

requestAnimationFrame 这个api 一般可以完成一些动画,在这里也可以适当运用一下,监听容器元素的与适口的相对位置,如果在适口下面就表示还没滚动到顶部,否则就是已经滚动到顶部,已经在吸顶的状态了。然后改变一下粘性定位元素的样式到自己喜欢的样子,否则取消这些样式,就能实现固定样式和绝对样式的不同效果了。

写一段js代码轻松拿捏了

let lastY = -1
  function updatePositioin (y) {
    if (y === lastY) {
      return
    }
    lastY = y
    const fixBanner = document.querySelector('.aaa')
    if (!fixBanner) {
      return
    }

    const top = fixBanner.getBoundingClientRect().top
    const dom = document.querySelector('#oo')

    if (top < 0) {
      dom.style.background = "#99f"
    } else {
      dom.style.background = "#098"
    }
  }

  function updateFixBanner () {
    const y = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
    updatePositioin(y)
    window.requestAnimationFrame(updateFixBanner)
  }

  window.requestAnimationFrame(updateFixBanner);

getBoundingClientRect

getBoundingClientRect 这个dom方法获取元素与适口的相对位置。无需考虑滚动的高度。