如何在移动设备上防止主体内容滚动但允许导航滚动?

17

我正在尝试为我的页面创建一个“离屏导航”。当导航打开时,我希望主体内容不可滚动,但我仍希望能够在导航菜单内部滚动,如果它超出了可见区域。

同时,当菜单打开时,我希望主体内容保持在同一位置(我找到了一个解决方案,让我在菜单打开时向主体添加position:fixed,但这会导致页面向顶部滚动)。

$(function() {
  $('.menu-toggle').click(function() {
    $('body').toggleClass('menu-open');
  });
});
body.menu-open {
  overflow:hidden; /* this does not prevent scrolling in mobile safari */
}

.menu-toggle {
  font-size:40px;
  cursor:pointer;
}

nav {
  background:#fff;
  width:100%;
  position:absolute;
  left:-100%;
}
  .menu-open nav {
    left:0;
  }
  nav ul {
    margin:0;
    padding:0;
    list-style-type:none;
  }
  nav ul li {
    padding:20px 0 20px 10px;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
  <header>
    <span class="menu-toggle">=</span>
    <nav>
      <ul>
        <li>Link 1</li>
        <li>Link 2</li>
        <li>Link 3</li>
        <li>Link 4</li>
        <li>Link 5</li>
        <li>Link 6</li>
        <li>Link 7</li>
        <li>Link 8</li>
        <li>Link 9</li>
        <li>Link 10</li>
      </ul>
    </nav>
  </header>

  <div class="body-content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ac magna sollicitudin, tincidunt nisl sed, eleifend diam. Maecenas venenatis semper mauris. In faucibus congue sapien, ultrices efficitur ante pulvinar id. Duis eget egestas sem. Nullam tincidunt purus ut molestie dignissim. Nunc dictum elit arcu. Curabitur vitae magna tortor. Proin lacinia, nisi sit amet gravida pellentesque, orci neque tempor nunc, sit amet lobortis magna nulla id lorem.

Etiam suscipit massa ut diam sollicitudin fringilla ac ac mauris. Vestibulum pretium semper urna. Nulla risus nibh, sollicitudin eget volutpat sit amet, fermentum non enim. Praesent gravida metus in leo pharetra congue. Maecenas augue purus, malesuada tempor venenatis at, maximus at elit. Phasellus ipsum nunc, posuere eu metus in, mattis imperdiet sem. Duis non ultrices mi. Mauris nibh ex, varius vel ipsum vel, fermentum semper tellus. Integer fringilla fringilla pharetra. Vivamus eleifend rhoncus mi at iaculis. Proin suscipit lorem justo. Nulla mauris libero, dapibus a augue et, varius mollis nulla. Etiam iaculis convallis quam. Nulla semper urna vel turpis blandit, in fermentum nunc lobortis. Ut varius dui ac enim fringilla condimentum.

Vivamus in condimentum leo. In ullamcorper lacus quam, elementum dictum elit scelerisque non. Pellentesque commodo augue imperdiet, consequat ipsum ut, ultrices libero. Sed non suscipit nisl. Nam tristique vel ante in condimentum. Morbi et sem pharetra, lacinia eros id, pulvinar enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse elementum ipsum ac scelerisque hendrerit. Ut tellus eros, aliquet sit amet aliquam et, rhoncus a eros.

Donec ut felis ex. Maecenas lobortis risus lacus, vitae vestibulum magna malesuada sit amet. Integer et magna pharetra, egestas lacus non, pretium nisl. Aenean malesuada urna et neque tincidunt tincidunt. In orci ligula, efficitur ut sagittis eget, vestibulum a leo. Phasellus convallis risus et elit sodales, vel sollicitudin arcu elementum. Nulla pretium orci sed aliquet feugiat. Fusce consequat pretium aliquet. Pellentesque dapibus placerat euismod. Aenean eget orci eget enim vestibulum interdum. Donec non enim vel lorem dapibus rhoncus sit amet vel risus. Nulla venenatis egestas mauris, et congue lectus. Etiam ac tristique risus.

Aliquam quis pretium nunc. Sed blandit hendrerit lacus, sit amet posuere velit sodales in. Praesent dapibus viverra turpis. Nam auctor volutpat urna, luctus venenatis nulla venenatis eu. Quisque quis purus vitae lorem blandit elementum a dapibus enim. Donec commodo lectus nec ante pulvinar fermentum. Etiam sodales ex sit amet dolor finibus suscipit. Maecenas luctus placerat congue. Morbi eget viverra lacus. Vivamus ultricies augue at tincidunt luctus. Maecenas vel pretium purus, in egestas nisi.
  </div>
</body>
</html>


在尝试了十几种解决方案后,我唯一能够解决这个问题的方法是使用固定位置和JS滚动恢复位。如果不是因为iOS的溢出隐藏,就足够了。很快我们希望能够有像样的触摸操作支持(再次提到iOS(或者我喜欢称之为新IE)阻碍了我们)。 - powerbuoy
你在任何地方设置了body的高度吗?例如:height: 100% - Chri.s
6个回答

7

如果您将内容放在一个div上,当菜单打开时,您可以隐藏它

这是一个可行的例子

$(function() {
  $('.menu-toggle').click(function() {
    $('body').toggleClass('menu-open');
  });
});
.menu-open .body-content {
  /* Hide content when menu is open */
  height: 0;
  overflow: hidden;
}

.menu-toggle {
  font-size: 40px;
  cursor: pointer;
}

nav {
  background: #fff;
  width: 100%;
  position: absolute;
  left: -100%;
}

.menu-open nav {
  left: 0;
}

nav ul {
  margin: 0;
  padding: 0;
  list-style-type: none;
}

nav ul li {
  padding: 20px 0 20px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
  <span class="menu-toggle">=</span>
  <nav>
    <ul>
      <li>Link 1</li>
      <li>Link 2</li>
      <li>Link 3</li>
      <li>Link 4</li>
      <li>Link 5</li>
      <li>Link 6</li>
      <li>Link 7</li>
      <li>Link 8</li>
      <li>Link 9</li>
      <li>Link 10</li>
    </ul>
  </nav>
</header>

<div class="body-content">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ac magna sollicitudin, tincidunt nisl sed, eleifend diam. Maecenas venenatis semper mauris. In faucibus congue sapien, ultrices efficitur ante pulvinar id. Duis eget egestas sem. Nullam tincidunt
  purus ut molestie dignissim. Nunc dictum elit arcu. Curabitur vitae magna tortor. Proin lacinia, nisi sit amet gravida pellentesque, orci neque tempor nunc, sit amet lobortis magna nulla id lorem. Etiam suscipit massa ut diam sollicitudin fringilla
  ac ac mauris. Vestibulum pretium semper urna. Nulla risus nibh, sollicitudin eget volutpat sit amet, fermentum non enim. Praesent gravida metus in leo pharetra congue. Maecenas augue purus, malesuada tempor venenatis at, maximus at elit. Phasellus ipsum
  nunc, posuere eu metus in, mattis imperdiet sem. Duis non ultrices mi. Mauris nibh ex, varius vel ipsum vel, fermentum semper tellus. Integer fringilla fringilla pharetra. Vivamus eleifend rhoncus mi at iaculis. Proin suscipit lorem justo. Nulla mauris
  libero, dapibus a augue et, varius mollis nulla. Etiam iaculis convallis quam. Nulla semper urna vel turpis blandit, in fermentum nunc lobortis. Ut varius dui ac enim fringilla condimentum. Vivamus in condimentum leo. In ullamcorper lacus quam, elementum
  dictum elit scelerisque non. Pellentesque commodo augue imperdiet, consequat ipsum ut, ultrices libero. Sed non suscipit nisl. Nam tristique vel ante in condimentum. Morbi et sem pharetra, lacinia eros id, pulvinar enim. Lorem ipsum dolor sit amet,
  consectetur adipiscing elit. Suspendisse elementum ipsum ac scelerisque hendrerit. Ut tellus eros, aliquet sit amet aliquam et, rhoncus a eros. Donec ut felis ex. Maecenas lobortis risus lacus, vitae vestibulum magna malesuada sit amet. Integer et magna
  pharetra, egestas lacus non, pretium nisl. Aenean malesuada urna et neque tincidunt tincidunt. In orci ligula, efficitur ut sagittis eget, vestibulum a leo. Phasellus convallis risus et elit sodales, vel sollicitudin arcu elementum. Nulla pretium orci
  sed aliquet feugiat. Fusce consequat pretium aliquet. Pellentesque dapibus placerat euismod. Aenean eget orci eget enim vestibulum interdum. Donec non enim vel lorem dapibus rhoncus sit amet vel risus. Nulla venenatis egestas mauris, et congue lectus.
  Etiam ac tristique risus. Aliquam quis pretium nunc. Sed blandit hendrerit lacus, sit amet posuere velit sodales in. Praesent dapibus viverra turpis. Nam auctor volutpat urna, luctus venenatis nulla venenatis eu. Quisque quis purus vitae lorem blandit
  elementum a dapibus enim. Donec commodo lectus nec ante pulvinar fermentum. Etiam sodales ex sit amet dolor finibus suscipit. Maecenas luctus placerat congue. Morbi eget viverra lacus. Vivamus ultricies augue at tincidunt luctus. Maecenas vel pretium
  purus, in egestas nisi.
</div>


谢谢您的建议,不幸的是这对我的实现方式行不通,因为一些菜单链接将滚动到正文内容中的特定区域。 - user13286
喜欢单页导航吗? - user4914734

4
当您触发打开按钮时,您可以使用javascript禁用主体滚动并在菜单上启用它。当关闭菜单时,相反的操作可能会触发,重新启用主体滚动。
在菜单打开时:
$(".body-content").css({ overflow: "hidden" });

菜单关闭时:

$(".body-content").css({ overflow: "auto" });

不幸的是,这并不能防止移动设备上的正文内容滚动。 - user13286

3

只需将此添加到 CSS 中

.menu-open header nav {
height: 100vh;
overflow: auto;
}

这将使导航栏高度达到100%并启用滚动。如果您希望在移动设备上仅将其设置为100%高度,请将其放入@media查询中。


3

对于我的网站,以下方法完全有效。但是需要注意的是:使用此方法不应为body设置高度,例如:height: 100% for body.menu-open,否则每次打开导航栏后它将跳到顶部。

body.menu-open{
   overflow: hidden;
}
.menu-open nav{
   overflow: auto;
}

当然,还要记得你的其他样式 :)

不幸的是,在移动 Safari 上,将 overflow:hidden 应用于 body 无法防止滚动。 - user13286

3
我不确定这是否符合您的要求,但我已将您的导航设置为在屏幕顶部保持“固定”,并在导航上添加了一些jQuery代码,以便在页面中滚动到不同的部分。

 $(function () {
            $('.menu-toggle').on('click touch',function () {
                $('body').toggleClass('menu-open');
            });

            $('nav li').on('click touch',function () {
                var id = $(this).attr("id");
                var temp = id.split("_");
                id = temp[1];                                                
                $('html, body').animate({
                    scrollTop: $('#' + id).offset().top
                }, 500);


                $('body').toggleClass('menu-open');
            });
        });
        header {
            position: fixed !important;
            z-index: 10;
            background-color: #FFF;
            display: block;
            width:100%;
            top:0px;
        }


        .body-content{            
            
        }
        
        
        body.menu-open {
            overflow: hidden; /* this does not prevent scrolling in mobile safari */
        }

        .menu-toggle {
            font-size: 40px;
            cursor: pointer;
        }

        nav {
            background: #fff;
            width: 100%;
            position: fixed;
            left: -100%;        
        }

        .menu-open nav {
            left: 0;
            overflow-y:scroll;
        }

        nav ul {
            margin: 0;
            padding: 0;
            list-style-type: none;
        }

        nav ul li {
            padding: 20px 0 20px 10px;
        }

        .body-content {
            padding-top:20px;
            position:relative;
        }
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>

    <!-- jQuery library -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<body>
    <header>
        <span class="menu-toggle">=</span>
        <nav>
            <ul>
                <li id="to_loc1">Link 1</li>
                <li id="to_loc2">Link 2</li>
                <li id="to_loc3">Link 3</li>
                <li id="to_loc4">Link 4</li>
                <li id="to_loc5">Link 5</li>
                <li>Link 6</li>
                <li>Link 7</li>
                <li>Link 8</li>
                <li>Link 9</li>
                <li>Link 10</li>
            </ul>
        </nav>
    </header>

    <div class="body-content">
        <div id="loc1"><h1>Section 1 </h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ac magna sollicitudin, tincidunt nisl sed, eleifend diam. Maecenas venenatis semper mauris. In faucibus congue sapien, ultrices efficitur ante pulvinar id. Duis eget egestas sem. Nullam tincidunt purus ut molestie dignissim. Nunc dictum elit arcu. Curabitur vitae magna tortor. Proin lacinia, nisi sit amet gravida pellentesque, orci neque tempor nunc, sit amet lobortis magna nulla id lorem.</div>

        <div id="loc2"><h1>Section 2 </h1>Etiam suscipit massa ut diam sollicitudin fringilla ac ac mauris. Vestibulum pretium semper urna. Nulla risus nibh, sollicitudin eget volutpat sit amet, fermentum non enim. Praesent gravida metus in leo pharetra congue. Maecenas augue purus, malesuada tempor venenatis at, maximus at elit. Phasellus ipsum nunc, posuere eu metus in, mattis imperdiet sem. Duis non ultrices mi. Mauris nibh ex, varius vel ipsum vel, fermentum semper tellus. Integer fringilla fringilla pharetra. Vivamus eleifend rhoncus mi at iaculis. Proin suscipit lorem justo. Nulla mauris libero, dapibus a augue et, varius mollis nulla. Etiam iaculis convallis quam. Nulla semper urna vel turpis blandit, in fermentum nunc lobortis. Ut varius dui ac enim fringilla condimentum.</div>

        <div id="loc3"><h1>Section 3 </h1>Vivamus in condimentum leo. In ullamcorper lacus quam, elementum dictum elit scelerisque non. Pellentesque commodo augue imperdiet, consequat ipsum ut, ultrices libero. Sed non suscipit nisl. Nam tristique vel ante in condimentum. Morbi et sem pharetra, lacinia eros id, pulvinar enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse elementum ipsum ac scelerisque hendrerit. Ut tellus eros, aliquet sit amet aliquam et, rhoncus a eros.</div>

        <div id="loc4"><h1>Section 4 </h1>Donec ut felis ex. Maecenas lobortis risus lacus, vitae vestibulum magna malesuada sit amet. Integer et magna pharetra, egestas lacus non, pretium nisl. Aenean malesuada urna et neque tincidunt tincidunt. In orci ligula, efficitur ut sagittis eget, vestibulum a leo. Phasellus convallis risus et elit sodales, vel sollicitudin arcu elementum. Nulla pretium orci sed aliquet feugiat. Fusce consequat pretium aliquet. Pellentesque dapibus placerat euismod. Aenean eget orci eget enim vestibulum interdum. Donec non enim vel lorem dapibus rhoncus sit amet vel risus. Nulla venenatis egestas mauris, et congue lectus. Etiam ac tristique risus.</div>

        <div id="loc5"><h1>Section 5 </h1>Aliquam quis pretium nunc. Sed blandit hendrerit lacus, sit amet posuere velit sodales in. Praesent dapibus viverra turpis. Nam auctor volutpat urna, luctus venenatis nulla venenatis eu. Quisque quis purus vitae lorem blandit elementum a dapibus enim. Donec commodo lectus nec ante pulvinar fermentum. Etiam sodales ex sit amet dolor finibus suscipit. Maecenas luctus placerat congue. Morbi eget viverra lacus. Vivamus ultricies augue at tincidunt luctus. Maecenas vel pretium purus, in egestas nisi.</div>
    </div>
</body>

</html>


谢谢,但这似乎在移动设备上无法正常工作。当我点击菜单图标时,导航栏没有出现。 - user13286
1
我也注意到了。我将菜单监听器更改为同时监听点击和触摸事件...使用'.on('click touch')'。 我现在无法将文本代码上传到服务器,但我会看看今晚能否解决这个问题。 - Varlain Systems
我找到了罪魁祸首。我从头部类中删除了 **overflow="hidden"**。同时添加了 <meta name="viewport" content="width=device-width, initial-scale=1"> 这样在移动设备上布局看起来更大。 我在我的服务器上进行了快速测试: http://www.indowill.com/htmltest.html - Varlain Systems

0

所以这是我在尝试了几次后想出的最佳方法。

您可以使用 jQuerytoggle() 隐藏 body-content,当 navigation 打开时,因此当它 hideshow 时,其位置不会改变。

请确保在 body.menu-open 中设置 overflow-y: scroll;,以便 navigation 可以滚动。

以下是代码:

    $(function () {
      $('.menu-toggle').click(function () {
        $('body').toggleClass('menu-open');
        $('.body-content').toggle();
      });
    });
   body.menu-open {
      overflow-y: scroll;
      /* this does not prevent scrolling in mobile safari */
    }

    .menu-toggle {
      font-size: 40px;
      cursor: pointer;
    }

    nav {
      background: #fff;
      width: 100%;
      position: absolute;
      left: -100%;
    }

    .menu-open nav {
      left: 0;
    }

    nav ul {
      margin: 0;
      padding: 0;
      list-style-type: none;
    }

    nav ul li {
      padding: 20px 0 20px 10px;
    }
    
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>

<body>
  <header>
    <span class="menu-toggle">=</span>
    <nav>
      <ul>
        <li>Link 1</li>
        <li>Link 2</li>
        <li>Link 3</li>
        <li>Link 4</li>
        <li>Link 5</li>
        <li>Link 6</li>
        <li>Link 7</li>
        <li>Link 8</li>
        <li>Link 9</li>
        <li>Link 10</li>
      </ul>
    </nav>
  </header>

  <div class="body-content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ac magna sollicitudin, tincidunt nisl sed, eleifend diam. Maecenas
    venenatis semper mauris. In faucibus congue sapien, ultrices efficitur ante pulvinar id. Duis eget egestas sem. Nullam
    tincidunt purus ut molestie dignissim. Nunc dictum elit arcu. Curabitur vitae magna tortor. Proin lacinia, nisi sit amet
    gravida pellentesque, orci neque tempor nunc, sit amet lobortis magna nulla id lorem. Etiam suscipit massa ut diam sollicitudin
    fringilla ac ac mauris. Vestibulum pretium semper urna. Nulla risus nibh, sollicitudin eget volutpat sit amet, fermentum
    non enim. Praesent gravida metus in leo pharetra congue. Maecenas augue purus, malesuada tempor venenatis at, maximus
    at elit. Phasellus ipsum nunc, posuere eu metus in, mattis imperdiet sem. Duis non ultrices mi. Mauris nibh ex, varius
    vel ipsum vel, fermentum semper tellus. Integer fringilla fringilla pharetra. Vivamus eleifend rhoncus mi at iaculis.
    Proin suscipit lorem justo. Nulla mauris libero, dapibus a augue et, varius mollis nulla. Etiam iaculis convallis quam.
    Nulla semper urna vel turpis blandit, in fermentum nunc lobortis. Ut varius dui ac enim fringilla condimentum. Vivamus
    in condimentum leo. In ullamcorper lacus quam, elementum dictum elit scelerisque non. Pellentesque commodo augue imperdiet,
    consequat ipsum ut, ultrices libero. Sed non suscipit nisl. Nam tristique vel ante in condimentum. Morbi et sem pharetra,
    lacinia eros id, pulvinar enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse elementum ipsum
    ac scelerisque hendrerit. Ut tellus eros, aliquet sit amet aliquam et, rhoncus a eros. Donec ut felis ex. Maecenas lobortis
    risus lacus, vitae vestibulum magna malesuada sit amet. Integer et magna pharetra, egestas lacus non, pretium nisl. Aenean
    malesuada urna et neque tincidunt tincidunt. In orci ligula, efficitur ut sagittis eget, vestibulum a leo. Phasellus
    convallis risus et elit sodales, vel sollicitudin arcu elementum. Nulla pretium orci sed aliquet feugiat. Fusce consequat
    pretium aliquet. Pellentesque dapibus placerat euismod. Aenean eget orci eget enim vestibulum interdum. Donec non enim
    vel lorem dapibus rhoncus sit amet vel risus. Nulla venenatis egestas mauris, et congue lectus. Etiam ac tristique risus.
    Aliquam quis pretium nunc. Sed blandit hendrerit lacus, sit amet posuere velit sodales in. Praesent dapibus viverra turpis.
    Nam auctor volutpat urna, luctus venenatis nulla venenatis eu. Quisque quis purus vitae lorem blandit elementum a dapibus
    enim. Donec commodo lectus nec ante pulvinar fermentum. Etiam sodales ex sit amet dolor finibus suscipit. Maecenas luctus
    placerat congue. Morbi eget viverra lacus. Vivamus ultricies augue at tincidunt luctus. Maecenas vel pretium purus, in
    egestas nisi.
  </div>
</body>

</html>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接