[教程] 使用 CSS 和 JS 实现平滑滚动页面导航创建一个简单的平滑滚动页面导航

2025-06-04

[教程] 使用 CSS 和 JS 实现平滑滚动页面导航

创建简单流畅的滚动页面导航

在我的博客上可以找到更多文章,或者在 Github 上免费阅读 JavaScript 电子书,其中涵盖了从 ES6 到 2019 的所有新功能。
如果您想找到一个很棒的交互式教程场所,我推荐Educative(免责声明:该链接是附属的),我目前正在那里完成我的 JavaScript 课程。

 

创建简单流畅的滚动页面导航

导航栏包含指向页面不同部分的链接,是许多网站的常见功能。能够流畅地滚动页面而不是直接跳转到所需部分,可能会让用户体验从愉悦变为令人厌烦。在本篇简短教程中,我们将介绍如何在网页中实现一个简单的平滑滚动导航栏。  

 

结果

教程 3 gif  

 

任务

 

HTML

我们将要创建的页面结构非常简单: - 一个带有三个链接的导航栏 - 一个带有三个部分的内容区域 首先将下面的代码复制到body您的 html 文件的标签内。

    <!-- navigation -->
        <div id="navigation">
          <span><a href="#sectionLink1">
              Go to section 1
            </a></span>
          <span><a href="#sectionLink2">
              Go to section 2
            </a></span>
          <span><a href="#sectionLink3">
              Go to section 3
            </a></span>
        </div>
        <!-- content -->
        <div id="content">
          <div id="section1">Section 1</div>
          <div id="section2">Section 2</div>
          <div id="section3">Section 3</div>
        </div>

如您所见,我们的a标签有一个与目标区域的href不完全相同的。如果我们在点击链接时写入内容,页面会直接跳转到内容,而我们不希望出现这种情况,我们希望它能够平滑滚动,因此我们使用了类似(尽管命名不同)的命名,以避免这种我们计划覆盖的自动行为。  idhref="section1"

 

CSS

如果你现在查看这个页面,你会发现它和结果 gif 中的页面完全不一样。让我们打开style.css文件并将这段代码复制到里面。

    /* basic styling to make the links bigger */
    #navigation {
      display: flex;
      /* make the navbar alway stay on top */
      position: fixed;
      top: 0;
      width: 100%;
      background-color: white;
    }

    #navigation span {
      flex-grow: 1;
      height: 50px;
      border: 1px solid black;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    #navigation span a {
      display: inline-block;
    }

    /* when a link is clicked, it gets highlighted */
    .highlighted {
      color: red;
    }

    /* make each section taller and give them different colors */
    #content {
      margin-top: 50px;
    }

    #content div {
      height: 100vh;
      /* align the text in the middle */
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 3rem;
      font-weight: bold;
    }

    #section1 {
      background-color: lightcoral;
    }

    #section2 {
      background-color: lightblue;
    }

    #section3 {
      background-color: lightgreen;
    }

代码本身非常容易解释,您可以查看注释来澄清任何疑问。  

 

JavaScript

现在,到了本教程最重要的部分,让我们停下来思考一下如何实现我们想要的结果。我们需要为每个链接添加一个事件监听器,并将它们连接到目标部分,从而实现平滑的滚动行为。

    document.addEventListener("DOMContentLoaded", () => {
      //  little hack to detect if the user is on ie 11
      const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
      // get all the links with an ID that starts with 'sectionLink'
      const listOfLinks = document.querySelectorAll("a[href^='#sectionLink");
      // loop over all the links
      listOfLinks.forEach(function (link) {
        // listen for a click
        link.addEventListener('click',  () => {
          // toggle highlight on and off when we click a link
          listOfLinks.forEach( (link) => {
            if (link.classList.contains('highlighted')) {
              link.classList.remove('highlighted');
            }
          });
          link.classList.add('highlighted');
          // get the element where to scroll
          let ref = link.href.split('#sectionLink');
          ref = "#section" + ref[1];
          // ie 11 does not support smooth scroll, so we will simply scroll
          if (isIE11) {
            window.scrollTo(0, document.querySelector(ref).offsetTop);
          } else {
            window.scroll({
              behavior: 'smooth',
              left: 0,
              // top gets the distance from the top of the page of our target element
              top: document.querySelector(ref).offsetTop
            });
          }
        })
      })
    })

您可以看到,我添加了一个小技巧,使我们的代码可以在 Internet Explorer 11 上运行。尽管这是一个非常小众的网站,但如果您碰巧在开发企业软件,您可能不得不在某个时候处理它,所以我想值得帮助您。IE11 不支持平滑滚动,如果您还记得的话,在本教程的开头我解释了为什么我们对a标签使用了不同的命名,div因此,由于我们“禁用”了默认的点击行为,因此我们需要手动实现我们自己的版本,以使点击按钮将用户带到正确的部分。IE11 就到此为止,让我们更仔细地看一下代码:

     listOfLinks.forEach(function (link) {
        // listen for a click
        link.addEventListener('click',  () => {
          // toggle highlight on and off when we click a link
          listOfLinks.forEach( (link) => {
            if (link.classList.contains('highlighted')) {
              link.classList.remove('highlighted');
            }
          });
          link.classList.add('highlighted');

a首先,我们获取导航中使用的所有标签,并切换 CSS 类以在点击时对它们进行不同的样式设置。

    let ref = link.href.split('#sectionLink');
          ref = "#section" + ref[1];
          // ie 11 does not support smooth scroll, so we will simply scroll
          if (isIE11) {
            window.scrollTo(0, document.querySelector(ref).offsetTop);
          } else {
            window.scroll({
              behavior: 'smooth',
              left: 0,
              // top gets the distance from the top of the page of our target element
              top: document.querySelector(ref).offsetTop
            });
          }

ref接下来,我们将点击的链接编号存储在变量中,并用它构建目标部分ref = "#section" + ref[1];。之后,只需添加行为和目标部分的坐标即可创建滚动操作。完美!现在您知道如何在网站上创建流畅的滚动导航了。

继续按照您的方式实现它,并随时在这里分享您的尝试/项目的链接。


非常感谢你的阅读。更多详情,请关注我的DevTo账号或博客inspiredwebdev 。


书籍横幅

在AmazonLeanpub上获取我的电子书

文章来源:https://dev.to/albertomontalesi/tutorial-smooth-scrolling-page-navigation-with-css-js-57j5
PREV
数组迭代器速查表(JavaScript)
NEXT
每个人都必须知道的 10 个 JavaScript 字符串方法