Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Scroll animation in plain JavaScript without wasting too much if your time.
The question is published on by Tutorial Guruji team.
The question is published on by Tutorial Guruji team.
I am trying to build a scroll animation section when visitors click on the anchor. As you might notice the variable “id” will show #1, this will match the id value of the section itself. How could I add the scroll animation to this javascript?
var section = document.getElementsByTagName("section"), nav = document.getElementById("nav-bar"), navHeight = nav.offsetHeight, navAnchor = nav.querySelectorAll("li a"); for (var i = 0; i < navAnchor.length; i++) { var element = navAnchor[i]; element.addEventListener("click", function(e) { e.preventDefault(); var el = this, id = el.getAttribute("href"); function scrollTo(element, to, duration) { var element = element, to = section + id; console.log(id); if (duration <= 0) { return; } var difference = to - element.scrollTop; var perTick = difference / duration * 10; consolelo setTimeout(function() { element.scrollTop = element.scrollTop + perTick; if (element.scrollTop === to) return; scrollTo(element, to, duration - 10); }, 500); } }); }
ul li { list-style-type: none; display: inline-block; } li a { text-decoration: none; display: block; width: 120px; padding-top: 10px; padding-bottom: 10px; border: 1px solid black; text-align: center; } section { width: 100%; height: 300px; border: 1px solid red; }
<div class="nav-block" id="nav-bar"> <ul class="navbar-unordered-list"> <li class="link"> <a href="#1" class="active">Profile</a> </li> <li class="link"> <a href="#2" class="scroll">Personal Project</a> </li> <li class="link"> <a href="#3" class="scroll">Skills</a> </li> <li class="link"> <a href="#4" class="scroll">CSS Drawings</a> </li> <li class="link"> <a href="#5" class="scroll">Contact</a> </li> </ul> </div> <section class="sections section1" id="1"> 1 </section> <section class="sections section2" id="2"> 2 </section> <section class="sections section3" id="3"> 3 </section> <section class="sections section4" id="4"> 4 </section> <section class="sections section5" id="5"> 5 </section>
Answer
The reason you see it move at all is that you haven’t prevented the default action of following the link, which takes you to the anchor the link references. 🙂
Separately from that, the scrollTo
function shouldn’t be inside the event handler.
Assuming you want to adjust the main scrollbar, I wouldn’t use setInterval
, I’d use requestAnimationFrame
, see comments:
var section = document.getElementsByTagName("section"), nav = document.getElementById("nav-bar"), navHeight = nav.offsetHeight, navAnchor = nav.querySelectorAll("li a"), animate = findAnimationElement(); for (var i = 0; i < navAnchor.length; i++) { var element = navAnchor[i]; element.addEventListener("click", function(e) { var el = this, id = el.getAttribute("href"); e.preventDefault(); // <=== Don't follow the link scrollTo(document.getElementById(id.substring(1)), 300); // Skip the "#" on "#1" -----------^^^^^^^^^^^^^ }); } function findAnimationElement() { // Webkit browsers animate `body`, others animate `html` (the document element) var bodyCurrent = document.body.scrollTop; var docElCurrent = document.documentElement.scrollTop; document.documentElement.scrollTop = document.body.scrollTop = 10; var animate; if (document.body.scrollTop > 0) { animate = document.body; document.body.scrollTop = bodyCurrent; } else { animate = document.documentElement; document.documentElement.scrollTop = docElCurrent; } return animate; } function scrollTo(to, duration) { // When should we finish? var finishAt = Date.now() + duration; // Start requestAnimationFrame(tick); function tick() { // How many frames left? (60fps = 16.6ms per frame) var framesLeft = (finishAt - Date.now()) / 16.6; // How far do we have to go? var distance = to.getBoundingClientRect().top; if (distance <= 0) { // Done (this shouldn't happen, belt & braces) return; } // Adjust by one frame's worth if (framesLeft <= 1) { // Last call animate.scrollTop += distance; } else { // Not the last, adjust and schedule next animate.scrollTop += Math.max(1, distance / framesLeft); requestAnimationFrame(tick); } } }
ul li { list-style-type: none; display: inline-block; } li a { text-decoration: none; display: block; width: 120px; padding-top: 10px; padding-bottom: 10px; border: 1px solid black; text-align: center; } section { width: 100%; height: 300px; border: 1px solid red; }
<div class="nav-block" id="nav-bar"> <ul class="navbar-unordered-list"> <li class="link"> <a href="#1" class="active">Profile</a> </li> <li class="link"> <a href="#2">Personal Project</a> </li> <li class="link"> <a href="#3">Skills</a> </li> <li class="link"> <a href="#4">CSS Drawings</a> </li> <li class="link"> <a href="#5">Contact</a> </li> </ul> </div> <section class="sections section1" id="1"> 1 </section> <section class="sections section2" id="2"> 2 </section> <section class="sections section3" id="3"> 3 </section> <section class="sections section4" id="4"> 4 </section> <section class="sections section5" id="5"> 5 </section>
We are here to answer your question about Scroll animation in plain JavaScript - If you find the proper solution, please don't forgot to share this with your team members.