i'm using this code to highlight the navbar when scrolling into sections. Is it possible to change the URL in the address bar instantly when I scroll to an section? Can anyone help me?
Thanks in advance
const [current, setCurrent] = useState('')
const sections = document.querySelectorAll('h3')
const navLi = document.querySelectorAll('nav ul li')
window.addEventListener('scroll', () => {
sections.forEach(section => {
const sectionTop = section.offsetTop
if (window.pageYOffset >= sectionTop && (window.pageYOffset + 100) - sectionTop < 200 && current !== section.getAttribute('id')) {
setCurrent(section.getAttribute('id'))
}
})
})
useEffect(() => {
navLi.forEach(li => {
li.classList.remove('test')
if(li.classList.contains(current)) {
li.classList.add('test')
}
})
}, [current])
Use an intersection observer :) Try this locally with a small borwser window. It will not work with StackOverflow snippets due to CORS / iframe origin issues, the snippets are run in an iframe.
<p class="x">Bloop1</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p class="x">Bloop2</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p class="x">Bloop3</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<p>Bleep</p><p>Bleep</p><p>Bleep</p><p>Bleep</p>
<script>
// which elements to keep track of when they scroll into view
const elements = document.querySelectorAll(".x");
// this is observing when the element will come into view
const observer = new IntersectionObserver((x) => {
// this is just to get an example
const text = x[0].target.textContent;
console.log(text);
// this actually changes the URL
window.history.pushState(text, "Title", "/" + text);
});
// register the observer for each element we are interested in
elements.forEach((x) => {
observer.observe(x);
});
</script>