I have the following code in my Header.astro component:
const burger = document.querySelector("#burger");
const nav = document.querySelector("#nav");
if (burger && nav) {
burger.addEventListener("click", () => nav.classList.toggle("on"));
}
var toggler = document.getElementsByClassName("hc");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function() {
this.parentElement.parentElement.querySelector(".c").classList.toggle("on");
this.classList.toggle("hc-down");
});
}
This only works on page load. I understand it is because the DOM is not being reloaded (?). But unfortunately I can't find the solution. I have tried adding is: inline to my script tags but the problem persists.
I have tried adding is: inline to my script tags. I have read about using data-role="page" on other frameworks.
When using View Transitions, scripts are only loaded once meaning any references to an element will become null after they are replaced with a new element from the new page. In order to get around this you can use lifecycle hooks to reinitialize/clean up your scripts
function init() {
const burger = document.querySelector("#burger");
const nav = document.querySelector("#nav");
// Rest of script...
// Clean up by destroying instances and removing event listeners
document.addEventListener('astro:before-swap', () => {
// SomeClass.destroy()
// document.removeEventListener(...)
}, { once: true })
}
// Initialize on first load
init()
// Re-initialize after swapping pages
document.addEventListener("astro:after-swap", init)
You can also use the transition:persist directive to prevent an element from being swapped
View Transition Docs:
When you are using ViewTransitions you can just wrap your code into this code.
document.addEventListener("astro:page-load", () => {
// Your code here
});
You can find more information in this video. And also in documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With