最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - JavaScript Smooth Scrolling effect with scrollIntoView - Stack Overflow

programmeradmin0浏览0评论

Okay, I am attempting to get a single page (two divs), Primarily a splash screen, which when you click 'Enter site' it will scroll down smoothly to the 'main site', However it jumps to it, rather than smooth scrolling to the element.

How can I get it to scroll to that element smoothly without this jump effect?

Here is my a snippet:

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

Okay, I am attempting to get a single page (two divs), Primarily a splash screen, which when you click 'Enter site' it will scroll down smoothly to the 'main site', However it jumps to it, rather than smooth scrolling to the element.

How can I get it to scroll to that element smoothly without this jump effect?

Here is my a snippet:

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

If you click the button it will jump to the next div, i need it to scroll smoothly, rather than jump to the next div. Using pure javascript, everywhere else i have looked seems to have plug ins or uses jquery.

Share Improve this question edited Aug 21, 2023 at 20:54 Ricky asked Oct 5, 2016 at 15:36 RickyRicky 7913 gold badges8 silver badges30 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 2

For a more prehensive list of methods for smooth scrolling, see my answer here.


To scroll to a certain position in an exact amount of time, window.requestAnimationFrame can be put to use, calculating the appropriate current position each time. setTimeout can be used to a similar effect when requestAnimationFrame is not supported.

/*
   @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);
        }
    });
}

Demo:

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>

For more plex cases, the SmoothScroll.js library can be used, which handles smooth scrolling both vertically and horizontally, scrolling inside other container elements, different easing behaviors, scrolling relatively from the current position, and more.

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/gh/LieutenantPeacock/[email protected]/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>

Alternatively, you can pass an options object to window.scroll which scrolls to a specific x and y position and window.scrollBy which scrolls a certain amount from the current position:

// 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' 
});

Demo:

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

Modern browsers support the scroll-behavior CSS property, which can be used to make scrolling in the document smooth (without the need for JavaScript). Anchor tags can be used for this by giving the anchor tag a href of # plus the id of the element to scroll to). You can also set the scroll-behavior property for a specific container like a div to make its contents scroll smoothly.

Demo:

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

Your content.scrollIntoView({behaviour: "smooth"}); should work, however, I think 'behaviour' is spelt behavior.

I did develop a way of smooth scrolling with TypeScript, but you should be able to convert to JS quite easily:

View stackoverflow answer

If you don't want a straight jump, you should animate the scroll somehow.
With the help of jQuery is easy as that:

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

Look at this fiddle: https://jsfiddle/8501ckvn/


jQuery solves a lot of cross browser issues, but if you are looking for a pure javascript solution there are already many answers on Stackoverflow, i.e. look at Smooth scroll anchor links WITHOUT jQuery.

Assuming that you have JQuery as well.

You could make use of the following JQuery code to get a smooth scrolling effect

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

Let me know if it worked

发布评论

评论列表(0)

  1. 暂无评论