2

I have a question regarding Matrix fields.

I have a matrix field where one block will be used multiple times (around 4 or so) on each page. When that block scrolls into view I am firing a javascript event that triggers a CSS animation.

Because I want this to fire each time one of these blocks scrolls into view and then never fire again I would like to have a unique ID on each instance of the block.

Is there an easy way to do this? I was thinking I could somehow find the count for the number of times this block is on the page and then append that number to an ID to make it unique but I'm nt sure how to pull that off yet, or if there might be a better way.

2
  • I don't see why you'd need unique IDs for this? It depends how your JS is set up, but typically you might apply a function to all elements that have the same class name or data attribute, and use Intersection Observer to tell if they've entered the viewport. If you really do need unique IDs, you can use block.id. Apr 11, 2023 at 11:21
  • If you're looping through the Matrix field to display the blocks you can use loop.index in combination with block.type to generate a unique ID for each instance of a block. Apr 11, 2023 at 12:26

1 Answer 1

2

You don't need unique IDs to do this. Just use the same class for all the blocks that you want to have your animation on. Then use an Intersection Observer to toggle the class once those blocks scroll into view.

Here's a simple example:

const animatedBlocks = Array.from(document.getElementsByClassName('animated-block'));
const activeClass = 'animated-block--active';
const activationThreshold = .25;

const handleIntersectionChanges = function (entries, observer) {
    entries.forEach(({ target, intersectionRatio }) => {
        if (intersectionRatio > activationThreshold) {
            target.classList.add(activeClass);
        } else {
            target.classList.remove(activeClass);
        }
    });
}

const observer = new IntersectionObserver(handleIntersectionChanges, {
    threshold: [1 - activationThreshold, 0 + activationThreshold],
});
animatedBlocks.forEach(node => observer.observe(node))

This will find all elements with the class animated-block and add the animated-block--active class to them once they enter into view (as soon as at least 25% of the node are visible, change the activationThreshold to change that ratio). If you want to run the animation only once, remove the else clause – this one removes the class once the element leaves the viewport.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.