Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript is not working on page change in Astro

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.

like image 772
2536817 Avatar asked Oct 22 '25 05:10

2536817


2 Answers

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:

  • Script behavior during page navigation
  • Lifecycle events
  • Maintaining State
like image 98
Bryce Russell Avatar answered Oct 24 '25 14:10

Bryce Russell


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.

like image 32
ToledoX82 Avatar answered Oct 24 '25 15:10

ToledoX82