Smooth Scroll using vanilla javascript
by Raj Shekhar
HTML
<a class="smooth-scroll" href="#goal">Scroll To First Goal</a>
<a class="smooth-scroll" href="#goal-2">Scroll To Second Goal</a>
CSS
.goal {
background-color: tomato;
color: white;
}
JavaScript
// Create dummy text and anchor targets
for (let i = 0; i < 100; i++) {
const element = document.createElement('h1')
element.innerText = `Hello ${i} World`
document.body.appendChild(element)
if (i === 30) {
const targetElement = document.createElement('h1')
targetElement.innerText = 'First Goal'
targetElement.id = 'goal'
targetElement.classList.add('goal')
document.body.appendChild(targetElement)
}
if (i === 90) {
const targetElement = document.createElement('h1')
targetElement.innerText = 'Second Goal'
targetElement.id = 'goal-2'
targetElement.classList.add('goal')
document.body.appendChild(targetElement)
}
}
// Initialize anchor events
document.querySelectorAll('.smooth-scroll').forEach(anchor => {
anchor.onclick = (e) => {
e.preventDefault()
const href = anchor.getAttribute('href')
const target = document.querySelector(href)
const to = target.offsetTop
scrollTo(document.documentElement, to, 2000)
}
})
const scrollTo = (element, to, duration) => {
let start = element.offsetTop
let change = to - start
let currentTime = 0
let increment = 20;
const animateScroll = () => {
currentTime += increment;
const val = easeInOutQuad(currentTime, start, change, duration);
element.scrollTop = val;
if (currentTime < duration) {
setTimeout(animateScroll, increment);
}
}
animateScroll()
}
// Easing function -> easeInOutQuad
//
//t = current time
//b = start value
//c = change in value
//d = duration
const easeInOutQuad = (t, b, c, d) => {
t /= d / 2
if (t < 1) return c / 2 * t * t + b
t--
return -c / 2 * (t * (t - 2) - 1) + b
}