代码之家  ›  专栏  ›  技术社区  ›  Daniel Hilgarth Richard

滚动容器内的右侧固定边栏

  •  4
  • Daniel Hilgarth Richard  · 技术社区  · 6 年前

    这听起来像是以前被问过无数次,但我没有找到任何能真正解决我要解决的所有问题的方法。有了这个免责声明,以下是我想要实现的目标:

    1. 一个侧边栏,固定在右边
    2. 一个可以滚动的内容区域
    3. 内容区域的滚动条必须指向 正确的 侧边栏的
    4. 应该可以显示覆盖图
    5. 覆盖也应该是可滚动的
    6. 虽然覆盖是可见的,但基础内容区域不应该是可滚动的
    7. 导致基础内容区域的重新布局,例如由于 overflow: hidden

    我现在有两个解决方案,虽然很接近,但仍然不够好:
    解决方案1不能解决需求7。

    解决方案1:

    function showOverlay() {
      var style = document.body.style;
      style.overflow = 'hidden';
      document.getElementById('overlay').style.display = 'block';
    }
    
    function closeOverlay() {
      var style = document.body.style;
      style['overflow-y'] = 'scroll';
      document.getElementById('overlay').style.display = 'none';
    }
    * {
      margin: 0;
      box-sizing: border-box
    }
    html {
    }
    body {
      position: relative;
      width: 100%;
      overflow-y: scroll;
    }
    
    .content {
      position: relative;
      display: block;
      background-color: lightblue;
      border: 2px solid white;
      width: calc(100% - 60px)
    }
    
    .fixed {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      z-index: 1000;
      background-color: lightgreen;
      width: 60px;
      border: 2px solid black;
      text-align: right;
    }
    
    #overlay {
      display: none;
      position: fixed;
      z-index: 10000;
      left: 0;
      top: 0;
      bottom: 0;
      right: 0;
      background-color: rgba(32,32,32,0.5);
      overflow-y: scroll;
    }
    
    .overlay-content {
      margin: 50px auto;
      height: 1000px;
      width: 80%;
      background-color: yellow;
    }
    <div class="content">
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        Body<br/>
        <button onclick="showOverlay()">show overlay</button>
      </div>
    <div class="fixed">A<br/>B<br/>C</div>
    <div id="overlay">
      <div class="overlay-content">
        <button onclick="closeOverlay()">Close overlay</button>
      </div>
    </div>

    解决方案2:

    function showOverlay() {
      var style = document.body.style;
      style.top = '-' + document.documentElement.scrollTop + 'px';
      style.position = 'fixed';
      document.getElementById('overlay').style.display = 'block';
    }
    
    function closeOverlay() {
      var style = document.body.style;
      style.position = 'relative';
      style.top = 0;
      document.getElementById('overlay').style.display = 'none';
    }
    * {
    框大小:边框框
    html格式{
    }
    位置:相对位置;
    overflow-y:滚动;
    }
    
    .内容{
    位置:相对位置;
    显示:块;
    背景色:浅蓝色;
    边框:2件纯白;
    }
    
    位置:固定;
    顶部:0;
    右:0;
    底部:0;
    z指数:1000;
    背景色:浅绿色;
    边框:2件纯黑;
    }
    
    显示:无;
    左:0;
    顶部:0;
    底部:0;
    右:0;
    背景色:rgba(32,32,32,0.5);
    }
    
    .覆盖内容{
    高度:1000px;
    背景色:黄色;
    }
    <div class=“content”>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    正文<br/>
    <按钮onclick=“showOverlay()”>显示覆盖图</按钮>
    </部门>
    <div class=“fixed”><br/>B<br/>C</部门>
    <div id=“覆盖”>
    <div class=“覆盖内容”>
    <button onclick=“closeOverlay()”>关闭覆盖(</按钮>
    </部门>

    我认为解决方案1是两个方案中比较好的一个,但是有没有可能防止这种重新布局的发生呢?

    请注意,我正在尝试找到一个解决方案,不使用Javascript来检测滚动条的宽度。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Mosh Feu Alex Chen    6 年前

    body

    此外,还可以用 position: absolute 包装器。不同之处在于 position right: 0 . 这个 absolute 是相对于父级的(带有 position: relative )以及 fixed 总是相对于窗口。

    position: fixed )所以我们要补充 .fixed-inner 具有 pointer-events: auto 允许用户与侧边栏内容交互。

    function showOverlay() {
      //  var style = document.body.style;
      //  style.overflow = 'hidden';
      document.getElementById('overlay').style.display = 'block';
    }
    
    function closeOverlay() {
      //  var style = document.body.style;
      //  style['overflow-y'] = 'scroll';
      document.getElementById('overlay').style.display = 'none';
    }
    * {
      margin: 0;
      box-sizing: border-box
    }
    
    html,
    body {
      position: relative;
      height: 100%;
      overflow-y: hidden;
    }
    
    .wrapper {
      overflow-y: auto;
      position: relative;
      height: 100%;
    }
    
    .content {
      position: relative;
      display: block;
      background-color: lightblue;
      border: 2px solid white;
      width: calc(100% - 60px)
    }
    
    .fixed-wrapper {
      position: absolute;
      top: 0;
      right: 0;
      width: 60px;
      height: 100%;
    }
    
    .fixed {
      position: fixed;
      z-index: 1000;
      background-color: lightgreen;
      width: 60px;
      border: 2px solid black;
      text-align: right;
      height: 100%;
      top: 0;
      pointer-events: none;
    }
    
    .fixed .fixed-inner {
      pointer-events: auto;
    }
    
    #overlay {
      display: none;
      position: fixed;
      z-index: 10000;
      left: 0;
      top: 0;
      bottom: 0;
      right: 0;
      background-color: rgba(32, 32, 32, 0.5);
      overflow-y: scroll;
    }
    
    .overlay-content {
      margin: 50px auto;
      height: 1000px;
      width: 80%;
      background-color: yellow;
    }
    <div class="wrapper">
      <div class="content">
        Body<br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/> Body
        <br/>
        <button onclick="showOverlay()">show overlay</button>
      </div>
      <div class="fixed-wrapper">
        <div class="fixed">
          <div class="fixed-inner">
            <a href="https://google.com">A</a>
            <br/>B<br/>C
          </div>
        </div>
      </div>
    </div>
    <div id="overlay">
      <div class="overlay-content">
        <button onclick="closeOverlay()">Close overlay</button>
      </div>
    </div>