I'm trying to write a smooth scrolling function that can handle if the href needs to load a new page first then run the scroll.
I have seen a few options where adding /page-template.html#anchor
to the href, but with a dynamic site where the homepage url would just be /#anchor
.
So the below code isn't seeing the slash as a part of the target href.
const $anchor = $('a')
$anchor.on('click', function(event) {
if (this.hash !== "") {
event.preventDefault()
let hash = this.hash
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 800, function(){
window.location.hash = hash
})
}
})
Kind of worked out a way to achieve this, but it's not tremendously pretty. Any advice on improving it would be appreciated.
// If loading a page with a hash in the URL, scroll to it
if (window.location.hash) {
setTimeout(function() {
$('html, body').scrollTop(0)
$('html, body').animate({
scrollTop: $(window.location.hash).offset().top
}, 1000)
}, 0)
}
// Get the current url path
const currUrl = window.location.pathname
$anchor.on('click', function(e) {
// Get the href and a hash into variables
const href = $(this).attr('href')
const hash = this.hash
// If a hash is present
if (hash) {
// Check if there is a URl path before the hash
if (href.charAt(0) !== '#') {
// Check if this URL path matches the current page's href
if (currUrl == href.split('#')[0]) {
e.preventDefault()
// As they match, just run the scroll within the same page
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 800, function() {
window.location.hash = hash
})
}
// There is no URL accompanying the hash, so it's got to be within the same page
} else {
e.preventDefault()
// Run smooth scrolling within the page
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 800, function() {
window.location.hash = hash
})
}
}
})