简体   繁体   English

打开菜单时防止滚动

[英]Prevent scroll when open menu

I would like to use the apple style mobile menu on non-mobile larger screens. 我想在非移动大屏幕上使用苹果风格的移动菜单。 The menu is part of several elements visible in the body and it does not cover the entire screen. 菜单是体内可见的几个元素的一部分,并不覆盖整个屏幕。

Is it possible to prevent scrolling when the menu is opened? 打开菜单时是否可以防止滚动?

I know I could do that with 我知道我可以做到

position: fixed;
overflow: hidden;

but not sure where to place them. 但不确定将它们放置在哪里。

Michelle. 米歇尔。

 (function(){ var burger = document.querySelector('.burger-container'), header = document.querySelector('.header'); burger.onclick = function() { header.classList.toggle('menu-opened'); } }()); 
 @import url(https://fonts.googleapis.com/css?family=Ek+Mukta:200); body { margin: 0; line-height: 1.4; } .window { position: relative; display: block; width: 50%; height: 567px; float: left; margin: 20px; -webkit-box-shadow: 0 0 65px 0px rgba(0, 0, 0, 0.2); box-shadow: 0 0 65px 0px rgba(0, 0, 0, 0.2); overflow: hidden; border-radius: 3px; } .window .header { position: absolute; display: block; top: 0; left: 0; height: 50px; width: 100%; background: rgba(0, 0, 0, 0.8); overflow: hidden; -webkit-transition: all 0.5s ease-out, background 1s ease-out; transition: all 0.5s ease-out, background 1s ease-out; -webkit-transition-delay: 0.2s; transition-delay: 0.2s; z-index: 1; } .window .header .burger-container { position: relative; display: inline-block; height: 50px; width: 50px; cursor: pointer; -webkit-transform: rotate(0deg); transform: rotate(0deg); -webkit-transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; } .window .header .burger-container #burger { width: 18px; height: 8px; position: relative; display: block; margin: -4px auto 0; top: 50%; } .window .header .burger-container #burger .bar { width: 100%; height: 1px; display: block; position: relative; background: #FFF; -webkit-transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99); -webkit-transition-delay: 0s; transition-delay: 0s; } .window .header .burger-container #burger .bar.topBar { -webkit-transform: translateY(0px) rotate(0deg); transform: translateY(0px) rotate(0deg); } .window .header .burger-container #burger .bar.btmBar { -webkit-transform: translateY(6px) rotate(0deg); transform: translateY(6px) rotate(0deg); } .window .header .icon { display: inline-block; position: absolute; height: 100%; line-height: 50px; width: 50px; height: 50px; text-align: center; color: #FFF; font-size: 22px; left: 50%; -webkit-transform: translateX(-50%); transform: translateX(-50%); } .window .header .icon.icon-bag { right: 0; top: 0; left: auto; -webkit-transform: translateX(0px); transform: translateX(0px); -webkit-transition: -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); -webkit-transition-delay: 0.65s; transition-delay: 0.65s; } .window .header ul.menu { position: relative; display: block; padding: 0px 48px 0; list-style: none; } .window .header ul.menu li.menu-item { border-bottom: 1px solid #333; margin-top: 5px; -webkit-transform: scale(1.15) translateY(-30px); transform: scale(1.15) translateY(-30px); opacity: 0; -webkit-transition: opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99), opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99), opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); } .window .header ul.menu li.menu-item:nth-child(1) { -webkit-transition-delay: 0.49s; transition-delay: 0.49s; } .window .header ul.menu li.menu-item:nth-child(2) { -webkit-transition-delay: 0.42s; transition-delay: 0.42s; } .window .header ul.menu li.menu-item:nth-child(3) { -webkit-transition-delay: 0.35s; transition-delay: 0.35s; } .window .header ul.menu li.menu-item:nth-child(4) { -webkit-transition-delay: 0.28s; transition-delay: 0.28s; } .window .header ul.menu li.menu-item:nth-child(5) { -webkit-transition-delay: 0.21s; transition-delay: 0.21s; } .window .header ul.menu li.menu-item:nth-child(6) { -webkit-transition-delay: 0.14s; transition-delay: 0.14s; } .window .header ul.menu li.menu-item:nth-child(7) { -webkit-transition-delay: 0.07s; transition-delay: 0.07s; } .window .header ul.menu li.menu-item a { display: block; position: relative; color: #FFF; font-family: "Ek Mukta", sans-serif; font-weight: 100; text-decoration: none; font-size: 22px; line-height: 2.35; font-weight: 200; width: 100%; } .window .header.menu-opened { height: 100%; background-color: #000; -webkit-transition: all 0.3s ease-in, background 0.5s ease-in; transition: all 0.3s ease-in, background 0.5s ease-in; -webkit-transition-delay: 0.25s; transition-delay: 0.25s; } .window .header.menu-opened .burger-container { -webkit-transform: rotate(90deg); transform: rotate(90deg); } .window .header.menu-opened .burger-container #burger .bar { -webkit-transition: all 0.4s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: all 0.4s cubic-bezier(0.4, 0.01, 0.165, 0.99); -webkit-transition-delay: 0.2s; transition-delay: 0.2s; } .window .header.menu-opened .burger-container #burger .bar.topBar { -webkit-transform: translateY(4px) rotate(45deg); transform: translateY(4px) rotate(45deg); } .window .header.menu-opened .burger-container #burger .bar.btmBar { -webkit-transform: translateY(3px) rotate(-45deg); transform: translateY(3px) rotate(-45deg); } .window .header.menu-opened ul.menu li.menu-item { -webkit-transform: scale(1) translateY(0px); transform: scale(1) translateY(0px); opacity: 1; } .window .header.menu-opened ul.menu li.menu-item:nth-child(1) { -webkit-transition-delay: 0.27s; transition-delay: 0.27s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(2) { -webkit-transition-delay: 0.34s; transition-delay: 0.34s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(3) { -webkit-transition-delay: 0.41s; transition-delay: 0.41s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(4) { -webkit-transition-delay: 0.48s; transition-delay: 0.48s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(5) { -webkit-transition-delay: 0.55s; transition-delay: 0.55s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(6) { -webkit-transition-delay: 0.62s; transition-delay: 0.62s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(7) { -webkit-transition-delay: 0.69s; transition-delay: 0.69s; } .window .header.menu-opened .icon.icon-bag { -webkit-transform: translateX(75px); transform: translateX(75px); -webkit-transition-delay: 0.3s; transition-delay: 0.3s; } .window .content { font-family: "Ek Mukta", sans-serif; padding: 67px 4% 0; text-align: justify; overflow: scroll; max-height: 100%; } .window .content::-webkit-scrollbar { display: none; } .window .content h2 { margin-bottom: 0px; letter-spacing: 1px; } .window .content img { width: 95%; position: relative; display: block; margin: 75px auto 75px; } .window .content img:nth-of-type(2) { margin: 75px auto; } .outside-text { width: 40%; display: inline-block; } .outside-text p { margin: 40px; } 
 <div class="window"> <div class="header"> <div class="burger-container"> <div id="burger"> <div class="bar topBar"></div> <div class="bar btmBar"></div> </div> </div> <div class="icon icon-apple"></div> <ul class="menu"> <li class="menu-item"><a href="#">Mac</a></li> <li class="menu-item"><a href="#">iPad</a></li> <li class="menu-item"><a href="#">iPhone</a></li> <li class="menu-item"><a href="#">Watch</a></li> <li class="menu-item"><a href="#">TV</a></li> <li class="menu-item"><a href="#">Music</a></li> <li class="menu-item"><a href="#">Support</a></li> </ul> <div class="shop icon icon-bag"></div> </div> <div class="content"> <img src="https://images.apple.com/v/ipad-air-2/c/images/overview/performance_large.png" alt=""/> </div> </div> <div class="outside-text"> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> </div> 

Not quiet sure if this is what you actually want. 不安静地确定这是否是您真正想要的。 The following code prevent scrolling if the menu is opend! 如果打开菜单,以下代码将阻止滚动!

if(header.getAttribute("class").indexOf("menu-opened") > -1)
    alert("opend"); // opend
else
    alert("closed"); // closed

Check if class contains menu-opened. 检查类是否包含已打开的菜单。

EDIT: As Sergey Khmelevskoy mentioned in his answere it is very usefull if you scroll to top once the menu is open. 编辑:正如谢尔盖·赫梅列夫斯科伊(Sergey Khmelevskoy)在他的回答中提到的,如果菜单打开后滚动到顶部,这将非常有用。

 (function(){ var body = document.getElementsByTagName("body")[0], burger = document.querySelector('.burger-container'), header = document.querySelector('.header'); burger.onclick = function() { header.classList.toggle('menu-opened'); if(header.getAttribute("class").indexOf("menu-opened") > -1){ body.classList.add("overflow_hidden"); window.scrollTo(0, 0); // scroll to the top of the page } else body .classList.remove("overflow_hidden"); } }()); 
 @import url(https://fonts.googleapis.com/css?family=Ek+Mukta:200); body { margin: 0; line-height: 1.4; } .overflow_hidden { overflow-y: hidden !important; } .window { position: relative; display: block; width: 50%; height: 567px; float: left; margin: 20px; -webkit-box-shadow: 0 0 65px 0px rgba(0, 0, 0, 0.2); box-shadow: 0 0 65px 0px rgba(0, 0, 0, 0.2); overflow: hidden; border-radius: 3px; } .window .header { position: absolute; display: block; top: 0; left: 0; height: 50px; width: 100%; background: rgba(0, 0, 0, 0.8); overflow: hidden; -webkit-transition: all 0.5s ease-out, background 1s ease-out; transition: all 0.5s ease-out, background 1s ease-out; -webkit-transition-delay: 0.2s; transition-delay: 0.2s; z-index: 1; } .window .header .burger-container { position: relative; display: inline-block; height: 50px; width: 50px; cursor: pointer; -webkit-transform: rotate(0deg); transform: rotate(0deg); -webkit-transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; } .window .header .burger-container #burger { width: 18px; height: 8px; position: relative; display: block; margin: -4px auto 0; top: 50%; } .window .header .burger-container #burger .bar { width: 100%; height: 1px; display: block; position: relative; background: #FFF; -webkit-transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99); -webkit-transition-delay: 0s; transition-delay: 0s; } .window .header .burger-container #burger .bar.topBar { -webkit-transform: translateY(0px) rotate(0deg); transform: translateY(0px) rotate(0deg); } .window .header .burger-container #burger .bar.btmBar { -webkit-transform: translateY(6px) rotate(0deg); transform: translateY(6px) rotate(0deg); } .window .header .icon { display: inline-block; position: absolute; height: 100%; line-height: 50px; width: 50px; height: 50px; text-align: center; color: #FFF; font-size: 22px; left: 50%; -webkit-transform: translateX(-50%); transform: translateX(-50%); } .window .header .icon.icon-bag { right: 0; top: 0; left: auto; -webkit-transform: translateX(0px); transform: translateX(0px); -webkit-transition: -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); -webkit-transition-delay: 0.65s; transition-delay: 0.65s; } .window .header ul.menu { position: relative; display: block; padding: 0px 48px 0; list-style: none; } .window .header ul.menu li.menu-item { border-bottom: 1px solid #333; margin-top: 5px; -webkit-transform: scale(1.15) translateY(-30px); transform: scale(1.15) translateY(-30px); opacity: 0; -webkit-transition: opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99), opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99), opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99); } .window .header ul.menu li.menu-item:nth-child(1) { -webkit-transition-delay: 0.49s; transition-delay: 0.49s; } .window .header ul.menu li.menu-item:nth-child(2) { -webkit-transition-delay: 0.42s; transition-delay: 0.42s; } .window .header ul.menu li.menu-item:nth-child(3) { -webkit-transition-delay: 0.35s; transition-delay: 0.35s; } .window .header ul.menu li.menu-item:nth-child(4) { -webkit-transition-delay: 0.28s; transition-delay: 0.28s; } .window .header ul.menu li.menu-item:nth-child(5) { -webkit-transition-delay: 0.21s; transition-delay: 0.21s; } .window .header ul.menu li.menu-item:nth-child(6) { -webkit-transition-delay: 0.14s; transition-delay: 0.14s; } .window .header ul.menu li.menu-item:nth-child(7) { -webkit-transition-delay: 0.07s; transition-delay: 0.07s; } .window .header ul.menu li.menu-item a { display: block; position: relative; color: #FFF; font-family: "Ek Mukta", sans-serif; font-weight: 100; text-decoration: none; font-size: 22px; line-height: 2.35; font-weight: 200; width: 100%; } .window .header.menu-opened { height: 100%; background-color: #000; -webkit-transition: all 0.3s ease-in, background 0.5s ease-in; transition: all 0.3s ease-in, background 0.5s ease-in; -webkit-transition-delay: 0.25s; transition-delay: 0.25s; } .window .header.menu-opened .burger-container { -webkit-transform: rotate(90deg); transform: rotate(90deg); } .window .header.menu-opened .burger-container #burger .bar { -webkit-transition: all 0.4s cubic-bezier(0.4, 0.01, 0.165, 0.99); transition: all 0.4s cubic-bezier(0.4, 0.01, 0.165, 0.99); -webkit-transition-delay: 0.2s; transition-delay: 0.2s; } .window .header.menu-opened .burger-container #burger .bar.topBar { -webkit-transform: translateY(4px) rotate(45deg); transform: translateY(4px) rotate(45deg); } .window .header.menu-opened .burger-container #burger .bar.btmBar { -webkit-transform: translateY(3px) rotate(-45deg); transform: translateY(3px) rotate(-45deg); } .window .header.menu-opened ul.menu li.menu-item { -webkit-transform: scale(1) translateY(0px); transform: scale(1) translateY(0px); opacity: 1; } .window .header.menu-opened ul.menu li.menu-item:nth-child(1) { -webkit-transition-delay: 0.27s; transition-delay: 0.27s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(2) { -webkit-transition-delay: 0.34s; transition-delay: 0.34s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(3) { -webkit-transition-delay: 0.41s; transition-delay: 0.41s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(4) { -webkit-transition-delay: 0.48s; transition-delay: 0.48s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(5) { -webkit-transition-delay: 0.55s; transition-delay: 0.55s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(6) { -webkit-transition-delay: 0.62s; transition-delay: 0.62s; } .window .header.menu-opened ul.menu li.menu-item:nth-child(7) { -webkit-transition-delay: 0.69s; transition-delay: 0.69s; } .window .header.menu-opened .icon.icon-bag { -webkit-transform: translateX(75px); transform: translateX(75px); -webkit-transition-delay: 0.3s; transition-delay: 0.3s; } .window .content { font-family: "Ek Mukta", sans-serif; padding: 67px 4% 0; text-align: justify; overflow: scroll; max-height: 100%; } .window .content::-webkit-scrollbar { display: none; } .window .content h2 { margin-bottom: 0px; letter-spacing: 1px; } .window .content img { width: 95%; position: relative; display: block; margin: 75px auto 75px; } .window .content img:nth-of-type(2) { margin: 75px auto; } .outside-text { width: 40%; display: inline-block; } .outside-text p { margin: 40px; } 
 <div class="window"> <div class="header"> <div class="burger-container"> <div id="burger"> <div class="bar topBar"></div> <div class="bar btmBar"></div> </div> </div> <div class="icon icon-apple"></div> <ul class="menu"> <li class="menu-item"><a href="#">Mac</a></li> <li class="menu-item"><a href="#">iPad</a></li> <li class="menu-item"><a href="#">iPhone</a></li> <li class="menu-item"><a href="#">Watch</a></li> <li class="menu-item"><a href="#">TV</a></li> <li class="menu-item"><a href="#">Music</a></li> <li class="menu-item"><a href="#">Support</a></li> </ul> <div class="shop icon icon-bag"></div> </div> <div class="content"> <img src="https://images.apple.com/v/ipad-air-2/c/images/overview/performance_large.png" alt=""/> </div> </div> <div class="outside-text"> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> <p>Lorem ipsum</p> </div> 

I generally recommend javascript based solution instead of regular body overflow: hidden fix as page won't jump to the top when you open the menu somewhere in the middle of the page 我通常建议使用基于javascript的解决方案,而不是常规的主体overflow: hidden当您在页面中间的某个位置打开菜单时, overflow: hidden修复方法不会出现在页面顶部

 function preventDefault(e) {
    e = e || window.event;
    if (e.preventDefault)
      e.preventDefault();
    e.returnValue = false;
  }

  var preventKeys = {
    37: 1, 38: 1, 39: 1, 40: 1
  };

  function preventDefaultForScrollKeys(e) {
    if (preventKeys[e.keyCode]) {
      preventDefault(e);
      return false;
    }
  }

  function disableScroll() {
    var target = $('.page').get(0)
    if (window.addEventListener) // older FF
      target.addEventListener('DOMMouseScroll', preventDefault, false);
    target.onwheel = preventDefault; // modern standard
    target.onmousewheel = target.onmousewheel = preventDefault; // older browsers, IE
    target.ontouchmove = preventDefault; // mobile
    target.onkeydown = preventDefaultForScrollKeys;
  }

  function enableScroll() {
    var target = $('.page').get(0)
    if (window.removeEventListener)
      target.removeEventListener('DOMMouseScroll', preventDefault, false);
    target.onmousewheel = target.onmousewheel = null;
    target.onwheel = null;
    target.ontouchmove = null;
    target.onkeydown = null;
  }

The original idea is not mine, I found this on Stackoverflow long time ago and take this part from project to project. 最初的想法不是我的,我很久以前就在Stackoverflow上发现了这一点,并将这一部分从一个项目引入另一个项目。 Unfortunately, I can't credit an author. 不幸的是,我不能相信作者。 Please let me know the topic in comments below if you know one 如果您知道以下内容,请在下面的评论中让我知道这个主题

To keep overflow scrolling on the menu (if the height is greater than 100vh) you should make menu outside target disableScroll() / enableScroll() functions 要保持菜单上的溢出滚动(如果高度大于100vh),应使菜单位于目标disableScroll() / enableScroll()函数外部

ie

<body>
<div class="menu> .. menu .. </div>

<div class="page"> .. site content .. </div>
</body>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM