Kyv
Kyv

Reputation: 687

How to display elements inside a div one after another?

I'm trying to animate some elements. There are spans inside a content-wrapper div. Once we reach the div with the content-wrapper class, the b-fadein class is added to each span, and the animation should start, and the spans should appear one after another.

$(window).scroll(function() {
        $('.el').each(function(){
        var pos = $(this).offset().top;

        var topOfWindow = $(window).scrollTop();
            if (pos < topOfWindow+400) {
                $(this).addClass("b-fadein");
            }
        });
    });

Animation.

.b-fadein {
  /* hidden by default */
  opacity: 0;
  animation: fadeIn 0.5s linear forwards;
  animation-delay: calc(0.5 * var(--i));
}

@keyframes fadeIn {
  from {
    /* is not visible*/
    opacity: 0;
  }
  to {
    /* is visible */
    opacity: 1;
  }
}

HTML

<div class="content-wrapper" style="">
  <!-- 0 -->
  <span style="--i: 0; opacity:0;" class="el el1">1</span>
  <!-- 1 -->
  <span style="--i: 1; opacity:0;" class="el el2">2</span>
  <!-- 2 -->
  <span style="--i: 2; opacity:0;" class="el el3">3</span>
  <!-- if more elements, increase the --i css variable for next elements -->
</div>

Currently, the desired effect is only visible when each span inside content-wrapper is displayed as a line (flex-direction is set to column). But all spans can be on the same line.
The problem is that, if they are on the same line, they are displayed at the same time once we reach the content-wrapper.
How do we display the spans one after the other once we reach the content-wrapper div?

Upvotes: 1

Views: 911

Answers (2)

Nikesh Kp
Nikesh Kp

Reputation: 384

$('span').each(function(i) {
    (function(self) {
        setTimeout(function() {
            $(self).addClass('b-fadein');
        },(i*1500)+1500);
    })(this);
});

Just add this jquery code when you reach the content-wrapper. I think this will help you to show the spans one after another. I just added a setTimeout function to provide a delay for adding the class to your span.

Upvotes: 0

amirsinaa
amirsinaa

Reputation: 141

You don't need jQuery for that you can use javascript vanilla Intersection Observer API to keep track of your spans intersection ratio

basically, you need to follow these steps :

  1. add an opacity transition to the span element with the desired delay
  2. add base opacity:0 to the span element
  3. create an Intersection Observer
  4. change the current entry.target.style.opacity(current span) to '1' based on entry.intersectionRatio

demo :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <style type="text/css">
            body {
                /* for demo purposes only */
                margin: 30em 0;
            }
            body span {
                /* for demo purposes only */
                display: flex;
                flex-direction: row;
                opacity: 0;
                font-size: 1.5em;
                padding: 3.33em 0;
                transition: opacity 1200ms linear;
            }
        </style>

        <title>Intersection Observer API</title>
    </head>
    <body>
        <section id="content-wrapper">
            <span>span item</span>
            <span>span item</span>
            <span>span item</span>
            <span>span item</span>
            <span>span item</span>
            <span>span item</span>
            <span>span item</span>
            <span>span item</span>
            <span>span item</span>
        </section>

        <script>
            let observer = new IntersectionObserver(
                (entries, observer) => {
                    entries.forEach((entry) => {
                        if (entry.intersectionRatio) {
                            entry.target.style.opacity = '1'
                            observer.unobserve(entry.target)
                        }
                    })
                },
                { rootMargin: '0px 0px 100px 0px' },
            )
            document.querySelectorAll('span').forEach((span) => {
                observer.observe(span)
            })
        </script>
    </body>
</html>

complete info on Intersection Observer API : https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

Upvotes: 3

Related Questions