<p>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 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" rel="nofollow noreferrer">Intersection Observer</a> to toggle the class once those blocks scroll into view.</p>
<p>Here's a simple example:</p>
<pre class="lang-js prettyprint-override"><code>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 }) =&gt; {
        if (intersectionRatio &gt; activationThreshold) {
            target.classList.add(activeClass);
        } else {
            target.classList.remove(activeClass);
        }
    });
}

const observer = new IntersectionObserver(handleIntersectionChanges, {
    threshold: [1 - activationThreshold, 0 + activationThreshold],
});
animatedBlocks.forEach(node =&gt; observer.observe(node))
</code></pre>
<p>This will find all elements with the class <code>animated-block</code> and add the <code>animated-block--active</code> class to them once they enter into view (as soon as at least 25% of the node are visible, change the <code>activationThreshold</code> to change that ratio). If you want to run the animation only once, remove the <code>else</code> clause – this one removes the class once the element leaves the viewport.</p>

CC BY-SA 4.0
2023-04-11T13:06:41.410Z
This is the best way IMO. If you're already using Alpine Js there is an intersect observer plugin that makes it super easy https://alpinejs.dev/plugins/intersect
CreateSean
CC BY-SA 4.0
2023-04-11T12:42:54.467Z
2023-04-11T12:42:54.467Z
MoritzLost
<p>I have a question regarding Matrix fields.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>

CC BY-SA 4.0
2023-04-11T11:21:53.030Z
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`.
James Smith
CC BY-SA 4.0
2023-04-11T12:26:28.630Z
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.
Martin Spain
<matrix><blocks><block-types>
Generate a unique ID for each instance of a block from matrix field
# Generate a unique ID for each instance of a block from matrix field

(Asked by: username_0 on 2023-04-11)

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.

**Tags:** matrix, blocks, block-types
> **Comments:**
> **username_1**: 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`.  
> **username_2**: 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.  

---

## 1 answers

### Answer by username_3 on 2023-04-11. Score: 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.

> **Comments:**
> **username_4**: This is the best way IMO. If you're already using Alpine Js there is an intersect observer plugin that makes it super easy https://alpinejs.dev/plugins/intersect  

---

