【问题标题】:JavaScript Smooth Scrolling effect with scrollIntoView带有 scrollIntoView 的 JavaScript 平滑滚动效果
【发布时间】:2017-02-14 03:39:40
【问题描述】:

好的,我正在尝试获取一个页面(两个 div),主要是一个启动屏幕,当您单击“进入站点”时,它会平滑地向下滚动到“主站点”,但是它会跳转到它,而不是平滑滚动到元素。

如果没有这种跳转效果,我怎样才能让它顺利滚动到该元素?

这是我的一个sn-p:

splash = document.getElementById('intro');
content = document.getElementById('content');

function enterSite() {
  content.scrollIntoView({
    behaviour: "smooth"
  });
}
body {
  font-family: 'Archivo Narrow', sans-serif;
  margin: 0 auto;
  width: 100%;
  height: 100%;
}

html,
body {
  overflow: hidden;
}

main {
  width: 100%;
  height: 100%;
  position: relative;
}

#intro {
  background-image: url(https://i.imgsafe.org/51d0cf26df.jpg);
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  text-align: center;
  height: 100%;
}

#splash {
  margin: auto;
  width: 40%;
  background-color: rgba(56, 56, 56, 0.4);
  border-radius: 50px 50px;
}

#splash-p {
  width: 70%;
  font-size: 1.2em;
  line-height: 1.5em;
  margin: auto;
  text-align: center;
  padding-top: 10px;
  color: #fff;
}

.btn {
  width: 35%;
  margin: auto;
  margin-top: 10px;
  margin-bottom: 10px;
}

/* Main Content Page */

article {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: red;
}
<div id="intro">
  <div id="splash">
    <p id="splash-p">Just a load of text repeated</p>
    <input
      type="image"
      src="Images/Button.png"
      class="btn"
      onclick="enterSite()"
    />
  </div>
</div>
<article id="content">Just a load of text repeated</article>

如果您单击按钮,它将跳转到下一个 div,但我需要它平滑滚动而不是跳转到下一个 div,使用纯 javascript,我看过的其他任何地方似乎都有插件或使用 jquery。

【问题讨论】:

    标签: javascript html css js-scrollintoview


    【解决方案1】:

    更全面的平滑滚动方法列表见我的回答here


    要在准确的时间内滚动到某个位置,可以使用window.requestAnimationFrame,每次计算适当的当前位置。在不支持requestAnimationFrame 时,可以使用setTimeout 达到类似的效果。

    /*
       @param pos: the y-position to scroll to (in pixels)
       @param time: the exact amount of time the scrolling will take (in milliseconds)
    */
    function scrollToSmoothly(pos, time) {
        var currentPos = window.pageYOffset;
        var start = null;
        if(time == null) time = 500;
        pos = +pos, time = +time;
        window.requestAnimationFrame(function step(currentTime) {
            start = !start ? currentTime : start;
            var progress = currentTime - start;
            if (currentPos < pos) {
                window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
            } else {
                window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
            }
            if (progress < time) {
                window.requestAnimationFrame(step);
            } else {
                window.scrollTo(0, pos);
            }
        });
    }
    

    演示:

    function scrollToSmoothly(pos, time) {
        var currentPos = window.pageYOffset;
        var start = null;
        if(time == null) time = 500;
        pos = +pos, time = +time;
        window.requestAnimationFrame(function step(currentTime) {
            start = !start ? currentTime : start;
            var progress = currentTime - start;
            if (currentPos < pos) {
                window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
            } else {
                window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
            }
            if (progress < time) {
                window.requestAnimationFrame(step);
            } else {
                window.scrollTo(0, pos);
            }
        });
    }
    
    document.getElementById("toElement").addEventListener('click', function(e) {
      var elem = document.querySelector("div");
      scrollToSmoothly(elem.offsetTop);
    });
    document.getElementById("toTop").addEventListener('click', function(e){
      scrollToSmoothly(0, 700);
    });
    <button id="toElement">Scroll To Element</button>
    <div style="margin: 1000px 0px; text-align: center;">Div element
      <button id="toTop">Scroll back to top</button>
    </div>

    对于更复杂的情况,可以使用SmoothScroll.js library,它可以处理垂直和水平平滑滚动、在其他容器元素内滚动、不同的缓动行为、从当前位置相对滚动等等。

    document.getElementById("toElement").addEventListener('click', function(e) {
      smoothScroll({toElement: document.querySelector('div'), duration: 500});
    });
    document.getElementById("toTop").addEventListener('click', function(e){
      smoothScroll({yPos: 0, duration: 700});
    });
    <script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/SmoothScroll@1.2.0/src/smoothscroll.min.js" integrity="sha384-UdJHYJK9eDBy7vML0TvJGlCpvrJhCuOPGTc7tHbA+jHEgCgjWpPbmMvmd/2bzdXU" crossorigin="anonymous"></script>
    <button id="toElement">Scroll To Element</button>
    <div style="margin: 1000px 0px; text-align: center;">Div element
      <button id="toTop">Scroll back to top</button>
    </div>

    或者,您可以将选项对象传递给 window.scroll 滚动到特定的 x 和 y 位置,window.scrollBy 从当前位置滚动一定量:

    // Scroll to specific values
    // scrollTo is the same
    window.scroll({
      top: 2500, 
      left: 0, 
      behavior: 'smooth' 
    });
    
    // Scroll certain amounts from current position 
    window.scrollBy({ 
      top: 100, // could be negative value
      left: 0, 
      behavior: 'smooth' 
    });
    

    演示:

    <button onClick="scrollToDiv()">Scroll To Element</button>
    <div style="margin: 500px 0px;">Div</div>
    <script>
    function scrollToDiv(){
    var elem = document.querySelector("div");
    window.scroll({
          top: elem.offsetTop, 
          left: 0, 
          behavior: 'smooth' 
    });
    }
    </script>

    现代浏览器支持scroll-behavior CSS property,可用于平滑滚动文档(无需JavaScript)。锚标签可以通过给锚标签一个href# 加上要滚动到的元素的id 来使用)。您还可以为div 等特定容器设置scroll-behavior 属性,以使其内容平滑滚动。

    演示:

    html, body{
      scroll-behavior: smooth;
    }
    <a href="#elem">Scroll To Element</a>
    <div id="elem" style="margin: 500px 0px;">Div</div>

    【讨论】:

    • iota - 这对我来说效果很好,谢谢!
    • @ReenaVerma 没问题。
    • @ReenaVerma 如果您有兴趣,我已经用更多方法更新了我的答案。
    • 这真是太棒了,谢谢你这样做。我会很好地解决这些问题并在未来了解它们:)
    【解决方案2】:

    您的content.scrollIntoView({behaviour: "smooth"}); 应该可以工作,但是,我认为“行为”的拼写是behavior

    我确实开发了一种使用 TypeScript 平滑滚动的方法,但是您应该可以很容易地转换为 JS:

    View stackoverflow answer

    【讨论】:

    【解决方案3】:

    如果你不想直接跳跃,你应该以某种方式为滚动设置动画。
    借助 jQuery 就这么简单:

    $("html, body").animate({ scrollTop: $([ELEMENT]).position().top }, 1000);
    

    看看这个小提琴:https://jsfiddle.net/8501ckvn/


    jQuery 解决了很多跨浏览器问题,但是如果您正在寻找 纯 javascript 解决方案,Stackoverflow 上已经有很多答案,即查看Smooth scroll anchor links WITHOUT jQuery

    【讨论】:

    • 我看到了那个问题,但它不是一个流畅的滚动,我想我只能放弃 javascript 并使用 css 了。
    • 好的,但如果我了解您的需求,我认为您不能仅使用 CSS 来控制滚动。反正是常见的模式,你也可以看看这篇文章:sitepoint.com/smooth-scrolling-vanilla-javascript
    • 为什么这是公认的答案???他说的是JAVASCRIPT,不是jquery。每个人都用 jQuery 回答 javascript 问题的热情真的让我很生气。
    • @Rup 你是对的,我感到内疚。但由于问题已经得到解答,我链接了 VanillaJS 解决方案。
    【解决方案4】:

    假设你也有 JQuery。

    您可以使用下面的 JQuery 代码来获得平滑的滚动效果

    function enterSite(){
        $('html, body').stop().animate({
            scrollTop: $('#content').offset().top
        }, 1500);
    });
    

    让我知道它是否有效

    【讨论】:

    • 恐怕我正在寻找一个普通的答案
    猜你喜欢
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    相关资源
    最近更新 更多