Reputation: 135
I created a smooth scroll with vanilla js. I made it ok for scrolling within page. But, when coming from another page, it goes to # position directory, then, starts animation. I would like them to like this: When clicking on anchor link in another page, the page shows up the top (window.pageYOffset) first, then, move to each link positions.
I wrote this event in snippet starting with if (urlHash) {}
const anchors = document.querySelectorAll('a[href^="#"]');
const header = document.querySelector('header').offsetHeight;
const urlHash = location.hash;
for ( let i = 0; i < anchors.length; i++ ) {
anchors[i].addEventListener('click', (e) => {
e.preventDefault();
const href= anchors[i].getAttribute("href");
if (href !== '#top') {
const target = document.getElementById(href.replace('#', ''));
const position = window.pageYOffset + target.getBoundingClientRect().top - header;
window.scroll({
top: position,
behavior: 'smooth'
});
} else {
window.scroll({
top: 0,
behavior: 'smooth'
});
}
});
}
window.addEventListener('DOMContentLoaded', (event) => {
if (urlHash) {
setTimeout(function () {
const urlTarget = document.getElementById(urlHash.replace('#', ''));
const urlPosition = window.pageYOffset + urlTarget.getBoundingClientRect().top - header;
window.scroll({
top: urlPosition,
behavior: 'smooth'
});
}, 1000);
}
});
* {margin: 0; padding: 0; list-style: none; box-sizing: border-box; text-decoration: none;}
header {position: fixed; width:100%; height: 100px; background: #ccc;}
div {height: 200vh;}
a {display: block;}
main{padding-top: 100px;}
<header>header</header>
<main>
<a href="#block01">Move to block01</a>
<a href="#block02">Move to block02</a>
<div id="block01">block01</div>
<div id="block02">block02</div>
<a href="#top">To top</a>
</main>
Upvotes: 1
Views: 504
Reputation: 1962
This cannot be done with JavaScript and anchor links, since by the time the JS runs, the page has already jumped to the anchor.
You can, however, do this with just a few lines of CSS.
/**
* Smooth scrolling on the whole document
*/
html {
scroll-behavior: smooth;
}
@media screen and (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}
You can learn more about how it works here: https://gomakethings.com/smooth-scrolling-links-with-only-css/
Upvotes: 1