JavaScript 使用 scrollIntoView 的平滑滚动效果

JavaScript Smooth Scrolling effect with scrollIntoView

好的,我正在尝试获取单个页面(两个 divs),主要是启动画面,当您单击 'Enter site' 时它会平滑地向下滚动到 'main site', 但是它跳转到它,而不是平滑滚动到该元素。

如果没有这个跳转效果,我怎样才能让它平滑地滚动到那个元素?

这是我的一个片段:

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.

假设您也有 JQuery。

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

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

让我知道它是否有效

如果你不想直接跳转,你应该以某种方式为滚动设置动画。
在 jQuery 的帮助下很容易:

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

看看这个fiddle:https://jsfiddle.net/8501ckvn/


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

有关平滑滚动的更全面的方法列表,请参阅我的回答 here


要在准确的时间内滚动到某个位置,当不支持 requestAnimationFrame 时,可以使用 window.requestAnimationFrame can be put to use, calculating the appropriate current position each time. 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 which scrolls to a specific x and y position and 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 of # 加上要滚动到的元素的 id,锚标签可以用于此目的)。您还可以为特定容器设置 scroll-behavior 属性,例如 div 以使其内容平滑滚动。

演示:

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

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

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

View Whosebug answer