【问题标题】:How to prevent scrolling further down from modal?如何防止从模态进一步向下滚动?
【发布时间】:2021-10-07 05:53:51
【问题描述】:

我有一个比屏幕高但比页面其余部分低的模态框。我希望用户能够在此模式内滚动,但不能在页面内滚动。

因此,它们不应该比模态框的底部边缘更深(即使在模态框下方,页面确实会继续,因为它比模态框高得多)。基本上,他们应该能够通过向上或向下滚动看到的只是模式。

有没有一种简单的方法可以用 CSS 实现这一点?如果没有,用 CSS + JS?

注意:我尝试了几件事,包括用 JS 计算模态框的高度并将该高度应用于 HTML 元素,但我不确定从那里去哪里。

Codepen

HTML:

<body>
  <div class="modal"></div>
  <div class="content"></div>
</body>

CSS:

body {
  background: blue;
}

.content {
  background: red;
  height: 3000px;
}

.modal {
  position: absolute;
  top: 50px;
  left: 50px;
  right: 50px;
  background: yellow;
  height: 1300px;
}

【问题讨论】:

  • 可能在打开模式时禁用其他所有内容的滚动?
  • 是的,但是怎么做?并且不要忘记模态框比屏幕高。
  • 你想禁用 body 的滚动?

标签: css


【解决方案1】:

我认为这会有所帮助,因为我制作了模态,当模态打开时,正文中的垂直滚动被隐藏,并且可以滚动模态的溢出内容。

$(document).ready(function() {
  $('.modal-toggle').on('click', function() {
    $('.modal').toggleClass('is-visible');
    $('body').toggleClass('modal-is-open');
  });
});
body.modal-is-open {
  overflow-y: hidden;
}

a {
  text-decoration: none;
  outline: none;
}

.modal {
  display: inline-block;
  background-color: #a3c62c;
  position: absolute;
  max-width: calc(100% - 30px);
  top: 15px;
  left: 15px;
  right: 15px;
  opacity: 0;
  visibility: hidden;
  height: 80vh;
  overflow-y: scroll;
}

.modal.is-visible {
  opacity: 1;
  visibility: visible;
  z-index: 9;
}

.modal-toggle {
  position: relative;
  background-color: #fff;
  padding: 5px;
  box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body>
  <div class="modal">
    <a href="#" class="modal-toggle">close modal
    </a>
    <p>
      There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum,
      you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary
      of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.
      There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem
      Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses
      a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage
      of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet.
      It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic
      words etc.
    </p>
  </div>
  <div class="content">
    <a href="#" class="modal-toggle">open modal</a>
    <p>
      There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum,
      you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration
      in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem
      Ipsum generators on the Internet tend to repeat There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable.
      If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat There are many variations of passages of Lorem Ipsum
      available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing
      hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised
      words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat
      There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem
      Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat
    </p>
  </div>
</body>

【讨论】:

    【解决方案2】:

    我不知道任何仅使用 css 的解决方案,但这里是您可以使用 JS 的方法。 CodePen

    let modalIsOpen = true;
    let btn = document.querySelector('#btn');
    let modal = document.querySelector('.modal');
    let content = document.querySelector('body');
    
    
    btn.addEventListener('click', ()=>{
      if(modalIsOpen){
        modal.style.display = 'block';
        content.style.overflow = 'hidden';
      } else {
        modal.style.display = 'none';
        content.style.overflow = 'auto';
      }
        modalIsOpen = !modalIsOpen;
    })
    body {
      background: blue;
    }
    
    .content {
      background: red;
      height: 3000px;
    }
    
    .modal {
      position: absolute;
      top: 50px;
      left: 50px;
      right: 50px;
      background: yellow;
      height: 1300px;
      overflow: scroll;
      display: none;
    }
    <body>
      <button id='btn'>Toggle Modal</button>
      <div class="modal"></div>
      <div class="content"></div>
    </body>

    只需检查模态框是否打开,如果打开,则隐藏正文溢出,防止用户滚动。

    编辑 我认为你应该像这样包装你的模态:

    .modalWrap{
      position: absolute;
      top:0;
      right: 0;
      height: 100%;
      width: 100%;
    }
    

    这充当可滚动容器,请查看w3schools tutorial on modals 以获得更好的想法。

    编辑 3 我添加了一个模态容器。 JsFiddle

    let modalIsOpen = false;
    let btn = document.querySelector('#btn');
    let modalWrap = document.querySelector('.modalWrap');
    let content = document.querySelector('body');
    
    
    btn.addEventListener('click', ()=>{
      if(modalIsOpen){
        modalWrap.style.display = 'flex';
        content.style.overflow = 'hidden';
      } else {
        modalWrap.style.display = 'none';
        content.style.overflow = 'auto';
      }
        modalIsOpen = !modalIsOpen;
    })
    body {
      background: blue;
    }
    
    button{
        z-index: 2;
        position: absolute;
        top: 2px;
        left: 2px;
    }
    
    .content {
      background: red;
      height: 3000px;
    }
    
    .modalWrap{
      position: fixed;
      top: 0;
      left: 0;
      height: 100%;
      width: 100%;
      display: none;
      overflow: auto;
      z-index: 1;
      padding: 50px;
      box-sizing: border-box;
      background-color: rgba(0,0,0,0.4);
    }
    
    .modal {
      background: yellow;
      position: relative;
      height: 2300px;
      top: 5px;
      width: 80%;
      margin: 0 auto;
    }
    <body>
      <button id='btn'>Toggle Modal</button>
      <div class='modalWrap'>
        <div class="modal"></div>  
      </div>
      <div class="content"></div>
    </body>

    当您打开模式时,身体滚动被禁用,因此您不会获得多个滚动条。 modalWrap 充当模态的容器,它是滚动的容器,模态可以根据需要设置任何高度。

    【讨论】:

    • 谢谢,但您的模式现在无法滚动:)
    • 我认为这就是您所需要的。不错!
    • 但它在我的机器(Windows、Chrome)上不起作用。我无法在此演示中滚动模式。
    • @drake035 检查最新的编辑,应该可以工作
    【解决方案3】:

    我不太明白你的问题,但如果你希望模型处于特定高度并查看它必须滚动的内容,请参阅此代码,我将模态的高度设置为 300px,以便查看其余部分您滚动其中的内容而不是通过页面底部

    body {
      background: blue;
    }
    
    .modal {
      position: absolute;
      top: 50px;
      left: 50px;
      right: 50px;
      height: 300px;
      overflow-y: scroll;
    }
    .content {
     height : 3000px ; 
     background : red ; 
    }
    <body>
      <div class="modal">
        <div class="content">
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
          <h1>yo</h1>
        </div>
      </div>
    </body>

    【讨论】:

    • 谢谢,但正如我所说,模态下方页面的其余部分不应滚动/可见
    • 现在检查代码是你想要的吗?让我知道。
    【解决方案4】:

    我认为给模态一个height: 1300px 不会让它自动滚动。你还需要声明overflow-y: scroll

    【讨论】:

      猜你喜欢
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多