javascript - 位置粘性顶部和底部

标签 javascript html css

有没有办法更新this gist这样侧边菜单导航在滚动期间延伸到视口(viewport)的底部,直到它被页脚向上推?它还应该保持其当前的 position: sticky 粘在视口(viewport)顶部的行为。

编辑 1:是的,这是下面链接问题的重复,但链接帖子中给出的答案实际上并没有解决问题!

编辑 2:澄清一下:我想要实现的只是一个侧边导航元素,它占据了可用的全部高度。当你向下滚动时,元素应该“粘”在视口(viewport)的顶部(这就是 position: stickytop:0 的完美表现。同样,当你向下滚动时元素的底部应该向下增长——它应该到视口(viewport)的底部,直到你向下滚动到页脚开始向上插入元素(在它应该收缩哪一点。基本上我想要一个侧边导航,它在视口(viewport)中占据尽可能多的空间,但永远不会扩展到视口(viewport)之外。如果它里面的内容多于视口(viewport)可以容纳的内容,那么这个溢出应该变成可滚动的——但整个元素总是在视口(viewport)的范围内!

编辑 3:我上传了一个 video to youtube .看到顶部和底部标记了吗?这就是我希望侧边导航元素的顶部和底部所在的位置。正是。基本上,我希望元素始终夹在 TOP 和 BOTTOM 之间。

[这基本上是this 的重新发布|问题...对此感到抱歉,但那里没有提供答案,我已经坚持了好几天了。]

我希望得到的效果有点像 position: sticky,带有顶部 底部触发点...请参阅下面的原始帖子的屏幕截图。我基本上是在尝试构建一个类似 this one on the gitbook site 的侧边导航.

纯 CSS 会很棒,但如果需要 JS,那也很好!请帮忙!

enter image description here

最佳答案

已编辑:影响左侧和右侧的 div。

我不确定你想要的效果是 gitbook site其左侧导航比主要内容短得多,而您的左侧导航比主要内容长得多。这是我认为您正在尝试实现的目标 - 使用 javascript。

*经过编辑以满足 OP 对要求的澄清。

将你的CSS更改为

    .page-layout-nav,
    .page-layout-aside {
      position: sticky;
      top: 0px;
      bottom:1px;
      overflow: auto;
      height: 100vh;
    }

然后尝试使用此脚本在滚动过程中调整左侧导航的高度。

    var doch = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

    document.addEventListener("DOMContentLoaded", function() {
      var onav = document.getElementsByClassName('page-layout-nav')[0];
      var onavr = document.getElementsByClassName('page-layout-aside')[0];
      var doch = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
      topspace = window.scrollY + doch - 16 - 50 - 2;
      onav.style.height = topspace + "px";
      onavr.style.height = topspace + "px";

    });

    function update() {
      var onav = document.getElementsByClassName('page-layout-nav')[0];
      var onavr = document.getElementsByClassName('page-layout-aside')[0];
      var ofooter = document.getElementsByClassName('page-footer')[0];
      var threshold = window.scrollY + doch + 16;
      var topspace = 0;
      if (window.scrollY < 16 + 50) {
        topspace = window.scrollY + doch - 16 - 50 - 2;
        onav.style.height = topspace + "px";
        onavr.style.height = topspace + "px";
      } else if (threshold >= ofooter.offsetTop) {
        onav.style.height = doch - threshold + ofooter.offsetTop + "px";
        onavr.style.height = doch - threshold + ofooter.offsetTop + "px";
      } else {
        onav.style.height = (doch - 1) + "px";
        onavr.style.height = (doch - 1) + "px";
      }

    }

    window.addEventListener('scroll', update);

完整代码及可运行结果如下:

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

<head>
  <meta charset="utf-8">
  <title>GistRun</title>
  <style>
    * {
      box-sizing: border-box;
    }
    
    html,
    body {
      margin: 0;
      padding: 0;
    }
    
    .page-header,
    .page-footer {
      height: 50px;
      background-color: #ccc;
    }
    
    .page-layout {
      display: flex;
      justify-content: space-between;
      align-items: flex-start;
      margin: 16px 0;
    }
    
    .page-layout-nav,
    .page-layout-main,
    .page-layout-aside {
      border: 1px dotted;
    }
    
    .page-layout-nav {
      order: 0;
      width: calc(25% - 16px);
    }
    
    .page-layout-main {
      order: 1;
      width: 50%;
    }
    
    .page-layout-aside {
      order: 2;
      width: calc(25% - 16px);
    }
    
    .page-layout-nav,
    .page-layout-aside {
      position: sticky;
      top: 0px;
      bottom:1px;
      overflow: auto;
      height: 100vh;
    }
  </style>
</head>

<body>
  <header class="page-header">
    Contoso
  </header>
  
  <div class="page-layout">
    <main class="page-layout-main">
      <h1>Hello World</h1>
      <p>lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar.
        lorem ipsum sumit dolar. </p>
      <h2>Foo</h2>
      <p>lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar.
        lorem ipsum sumit dolar. </p>
      <h2>Bar</h2>
      <p>lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar.
        lorem ipsum sumit dolar. </p>
      <h2>Foo</h2>
      <p>lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar.
        lorem ipsum sumit dolar. </p>
      <h2>Bar</h2>
      <p>lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar. lorem ipsum sumit dolar.
        lorem ipsum sumit dolar. </p>
    </main>

    <nav class="page-layout-nav">
      <ul>
        <li><a href="#">1st foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
      </ul>
    </nav>

    <aside class="page-layout-aside">
      <h2>In this article</h2>
      <ul>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
        <li><a href="#">foo</a></li>
      </ul>
    </aside>
  </div>

  <footer class="page-footer">
    foo bar baz
  </footer>

  <script>
    var doch = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

    document.addEventListener("DOMContentLoaded", function() {
      var onav = document.getElementsByClassName('page-layout-nav')[0];
      var onavr = document.getElementsByClassName('page-layout-aside')[0];
      var doch = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
      topspace = window.scrollY + doch - 16 - 50 - 2;
      onav.style.height = topspace + "px";
      onavr.style.height = topspace + "px";

    });

    function update() {
      var onav = document.getElementsByClassName('page-layout-nav')[0];
      var onavr = document.getElementsByClassName('page-layout-aside')[0];
      var ofooter = document.getElementsByClassName('page-footer')[0];
      var threshold = window.scrollY + doch + 16;
      var topspace = 0;
      if (window.scrollY < 16 + 50) {
        topspace = window.scrollY + doch - 16 - 50 - 2;
        onav.style.height = topspace + "px";
        onavr.style.height = topspace + "px";
      } else if (threshold >= ofooter.offsetTop) {
        onav.style.height = doch - threshold + ofooter.offsetTop + "px";
        onavr.style.height = doch - threshold + ofooter.offsetTop + "px";
      } else {
        onav.style.height = (doch - 1) + "px";
        onavr.style.height = (doch - 1) + "px";
      }

    }

    window.addEventListener('scroll', update);
  </script>
</body>

</html>

关于javascript - 位置粘性顶部和底部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59081001/

相关文章:

html - Flex-grow 不适用于列方向

javascript - 从下拉列表中选择类似的选项

jquery - 查找字体大小大于指定的元素

html - Horizo​​ntal::after line/bar 显示在段落之后,而不是标题

html - 如何基于子类为父类编写css?

Javascript html5如何将二进制数据转换为字符串

javascript - Rails 解析 Ransack 参数并提交

javascript - ID、唯一 ID、客户端 ID、唯一客户端 ID、静态客户端 ID?

javascript - iPad 滚动 - 标题仅在滚动结束时设置为固定

javascript - 无需滚动即可修复 HTML 表格标题