#not work with transition in layout

4 messages · Page 1 of 1 (latest)

static steppe
#

const { data } = Astro.props

<article class="service">
<div class="service__header">
{data.title}
</div>
<div class="service__body">
<div class="service__icon"></div>
<div class="service__title">
{data.title}
</div>
<div class="service__desc">
{data.desc}
</div>
</div>
</article>

<script>
document.querySelectorAll('.service').forEach((service) => {
const header = service.querySelector('.service__header')
const body = service.querySelector('.service__body')

    body.style.display = 'none'

    header.addEventListener('click', () => {
        header.style.display = 'none'
        body.style.display = 'block'
    })

    body.addEventListener('click', () => {
        header.style.display = 'block'
        body.style.display = 'none'
    })
})

</script>

junior whaleBOT
#

Hi @static steppe. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

The issue you're experiencing with transitions in your layout is likely related to how Astro handles client-side scripts and view transitions. Let's address this problem and provide some solutions based on the information from the knowledge sources.

  1. Script Behavior with View Transitions:
    When using view transitions in Astro, scripts may not re-run after page navigation as they do with full-page browser refreshes. To ensure your script runs properly with view transitions, you should wrap it in an event listener for the appropriate lifecycle event.

View Transitions Guide suggests using the astro:page-load event to run scripts after navigation:

<script>
  document.addEventListener('astro:page-load', () => {
    document.querySelectorAll('.service').forEach((service) => {
      const header = service.querySelector('.service__header')
      const body = service.querySelector('.service__body')

      body.style.display = 'none'

      header.addEventListener('click', () => {
        header.style.display = 'none'
        body.style.display = 'block'
      })

      body.addEventListener('click', () => {
        header.style.display = 'block'
        body.style.display = 'none'
      })
    })
  });
</script>
  1. Using data-astro-rerun:
    If you want the script to re-execute after every transition, you can add the data-astro-rerun attribute to your script tag. This is available for inline scripts that are not bundled and processed by Astro.
<script is:inline data-astro-rerun>
  // Your script content here
</script>
#
  1. Consider using Web Components:
    For more complex interactive components, you might want to consider using Web Components with custom elements. This approach can make your component more self-contained and easier to manage across page transitions.

Common Script Patterns provides an example of how to create a custom element:

<astro-service>
  <!-- Your service component HTML here -->
</astro-service>

<script>
  class AstroService extends HTMLElement {
    connectedCallback() {
      const header = this.querySelector('.service__header')
      const body = this.querySelector('.service__body')

      body.style.display = 'none'

      header.addEventListener('click', () => {
        header.style.display = 'none'
        body.style.display = 'block'
      })

      body.addEventListener('click', () => {
        header.style.display = 'block'
        body.style.display = 'none'
      })
    }
  }

  customElements.define('astro-service', AstroService)
</script>

By implementing one of these solutions, your service component should work correctly with Astro's view transitions. Remember to ensure that you have set up view transitions correctly in your project, as described in the View Transitions Guide.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: