打开菜单时阻止滚动

时间:2018-03-10 17:59:13

标签: javascript css

我想在非移动大屏幕上使用苹果风格的移动菜单。 菜单是身体中可见的几个元素的一部分,它不会覆盖整个屏幕。

打开菜单时是否可以阻止滚动?

我知道我可以用

做到这一点
position: fixed;
overflow: hidden;

但不确定放在哪里。

米歇尔。

(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>

2 个答案:

答案 0 :(得分:1)

不确定这是否是您真正想要的。如果菜单打开,以下代码会阻止滚动!

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

检查类是否包含菜单打开。

  

编辑:正如Sergey Khmelevskoy在回答中提到的那样,如果您在菜单打开后滚动到顶部则非常有用。

&#13;
&#13;
(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");
    }
}());
&#13;
@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;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我一般建议使用基于javascript的解决方案,而不是常规正文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;
  }

最初的想法不是我的,我很久以前就在Stackoverflow上找到了这个,并将这部分从项目转移到项目。不幸的是,我无法归功于作者。如果您知道一个

,请在下面的评论中告诉我这个主题

要在菜单上保持溢出滚动(如果高度超过100vh),您应该在目标disableScroll() / enableScroll()功能之外设置菜单

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

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