#client side rendering JS

57 messages · Page 1 of 1 (latest)

real badger
#

I have built a carousel using js, css and html. It works on a .html file but doesn’t work with Astro. I tried wrapping it in an eventListener(astro:pageload, () =>{. File. “dataset”, “slides” and “carousel” are all “possibly null, it says. Any advice?

vapid cedar
#

is:inline to make the script tag run on the client?

real badger
#

My Js is in a script tag at the bottom of my html. Styles are imported.

#

Does this answer your question?

proven violet
#

Can you send an actual code snippet or a stackblitz reproduction?

real badger
#

Just Js?

proven violet
#

Probably your astro file?

real badger
#

<script>
document.addEventListener("astro:page-load", () => {
const buttons = document.querySelectorAll("[data-carousel-button]");

buttons.forEach(button => {
button.addEventListener("click", () => {
const offset = button.dataset.carouselButton === "next" ? 1 : -1;
const carousel = button.closest("[data-carousel]"); // Find closest carousel container
const slides = carousel.querySelector("[data-slides]");
const activeSlide = slides.querySelector("[data-active]");

let newIndex = (slides.children.length + [...slides.children].indexOf(activeSlide) + offset) % slides.children.length; // Improved slide selection and looping

slides.children[newIndex].dataset.active = true;
if (activeSlide) {
  delete activeSlide.dataset.active; // Remove active state from previous slide
}
});
});

})

</script>

proven violet
#

If you know that those elements will always be there you can cast as Element

const carousel = button.closest("[data-carousel]") as Element

real badger
#

where do I put this line of code?

#

at the top?

proven violet
#

No so that's the same line as you have where you're defining carousel

<script>
document.addEventListener("astro:page-load", () => {
    const buttons = document.querySelectorAll("[data-carousel-button]");

    buttons.forEach(button => {
    button.addEventListener("click", () => {
    const offset = button.dataset.carouselButton === "next" ? 1 : -1;

    // Added the Typescript casts below 👇
    const carousel = button.closest("[data-carousel]") as Element; // Adding as Element here
    const slides = carousel.querySelector("[data-slides]") as Element; // Adding as Element here
    const activeSlide = slides.querySelector("[data-active]") as Element; // Adding as Element here

    let newIndex = (slides.children.length + [...slides.children].indexOf(activeSlide) + offset) % slides.children.length; // Improved slide selection and looping

    slides.children[newIndex].dataset.active = true;
    if (activeSlide) {
      delete activeSlide.dataset.active; // Remove active state from previous slide
    }
    });
    });
})

</script>
real badger
#

Thanks, it stilldoesn't recognize dataset

proven violet
#

I'd probably do something like

const slideChild = slides.children[newIndex] as Element
slideChild.dataset.active = true
real badger
#

Slides, newIndex and dataset are all complaining

#

Document is not defined it says

#
    document.addEventListener("astro:page-load", () => {
        const buttons = document.querySelectorAll("[data-carousel-button]");
        const slideChild = slides.children[newIndex] as Element
slideChild.dataset.active = true
        buttons.forEach(button => {
        button.addEventListener("click", () => {
        const offset = button.dataset.carouselButton === "next" ? 1 : -1;
    
        // Added the Typescript casts below 👇
        const carousel = button.closest("[data-carousel]") as Element; // Adding as Element here
        
        const slides = carousel.querySelector("[data-slides]") as Element; // Adding as Element here
        const activeSlide = slides.querySelector("[data-active]") as Element; // Adding as Element here
    
        let newIndex = (slides.children.length + [...slides.children].indexOf(activeSlide) + offset) % slides.children.length; // Improved slide selection and looping
    
        slides.children[newIndex].dataset.active = true;
        if (activeSlide) {
          delete activeSlide.dataset.active; // Remove active state from previous slide
        }
        });
        });
    })
    
    </script>```
proven violet
#

Are you able to screenshot or copy and paste the errors you're getting?

real badger
#

can you see the screenshots that I uploaded, they don't appear to be in the chat.

#

now they appear to be in the chat

#

I need to run an errand this morning, I will check back in. a couple of hours. I appreciate your help!

real badger
#

Maybe I should explore server side rendering for the carousel??

ember snow
#

The error about document not existing is coming form CustomCarousel.js. Where are you importing that script and what's on line 2 of it?

real badger
#

This is what I am importing: There's no JS file

#

Before, all the pictures were stacked, but would not scroll.

real badger
#

I found this list of errors. I'm not sure what to do with it:

#
    document.addEventListener("astro:page-load", () => {
        const buttons = document.querySelectorAll("[data-carousel-button]");
        buttons.forEach(button => {
        button.addEventListener("click", () => {
        const offset = button.dataset.carouselButton === "next" ? 1 : -1;
    
        // Added the Typescript casts below 👇
        const carousel = button.closest("[data-carousel]") as Element; // Adding as Element here
        
        const slides = carousel.querySelector("[data-slides]") as Element; // Adding as Element here
        const activeSlide = slides.querySelector("[data-active]") as Element; // Adding as Element here
    
        let newIndex = (slides.children.length + [...slides.children].indexOf(activeSlide) + offset) % slides.children.length; // Improved slide selection and looping
    
        slides.children[newIndex].dataset.active = true;
        if (activeSlide) {
          delete activeSlide.dataset.active; // Remove active state from previous slide
        }
        });
        });
    })
    
    </script>```.  here's the file
proven violet
#

Try typing them as HTMLElement instead of Element, I think maybe dataset is only on HTMLElement?

real badger
#

how do I do that?

proven violet
#

Change where it says as Element to as HTMLElement. So this is called "casting" in Typescript, where we are telling Typescript that something is a specific type.

So we're telling it that your carousel variable, actually has the type HTMLElement

proven violet
real badger
#

Thank you. I want to try a couple more things first

real badger
proven violet
real badger
#

Sorry I didn’t communicate well. Family came and I needed to entertain them. I’ll do that now.

#

everyone is sleeping

proven violet
#

Ok, so... That repo doesn't seem to be working, there's some components and stuff missing... What exactly was your error again? Was it just the type error of the carousel.dataset ?

real badger
#

I have had time to fix the code so that I now have the same experience as on my computer

#

Sorry for sending before it was ready

proven violet
#

Ok, so that previous link still has some errors. But tbh you're not really trying to rewrite your whole site! If you can create a reproduction of your issue with the minimum amount of code the better!

So I think your error was a typing issue, correct?

real badger
#

It worked on my end, I’ll look in a couple hours

#

Maybe I didn’t save it

real badger
#

this is what I see

#

Let me know if you see something else. how I fix it. Thanks,

ember snow
#

I see this: "The collection "blog" does not exist or is empty. Ensure a collection directory with this name exists."

But I don't see the error messages you mentioned earlier

real badger
#

The problem is that the js does not work.

#

The photos should sycle with clicking the arrows

real badger
#

Help me out, why does yours work, and mine does not. I have looked line by line in the js and html. What have I missed?

#

found it, thank you so much!!

ember snow
# real badger Help me out, why does yours work, and mine does not. I have looked line by line...

Yeah so I'm glad it works. Wasn't 100% sure if that's what you were going for but it's a simple fix. You were using the astro:page-load lifecycle event. But that doesn't work unless you import and use View Transitions.

So in Layout.astro line 3 I added:
import { ViewTransitions } from 'astro:transitions';

Then on line 38 I added: <ViewTransitions />

I took that from the docs here: https://docs.astro.build/en/guides/view-transitions/

You also had two <head> so I removed one

real badger
#

I appreciate your help. still working on that attention to detail thing!!

ember snow
#

Yeah it's terrible. Forget one word and your entire app breaks. If want to you can go through the astroJS tutorial and it has a section for ViewTransitions. It will explain it better than I can

#

I can't even find it in the tutorial now that I look. Maybe just the docs then 🙂

real badger
#

Do you have the link? I would love to know more about JS and astro!