0

I found code on SO that I was able to tweak to fit my needs but can't seem to get it all to work as desired. Basically I have some ul's whose li's fade in, then the list fades out and the process repeats itself through all ul's. I wan to add a delay between the time the ul's switch. So I'd like 'ul#one' to fade in it's li's then stay visible for 2 seconds, and then fade in the li's from 'ul#two'

Here is the markup:

<ul id="one" class="contracts">
   <li>one</li>
   <li>one</li>
   <li>one</li>
</ul>
<ul id="two" class="contracts">
   <li>one</li>
   <li>one</li>
   <li>one</li>
</ul>
...etc

and the js

function AnimateList($listItems, index, callback) {
    if (index >= $listItems.length) {
        $listItems.closest("ul.contracts").fadeOut(function() {
            $listItems.css("left","400px").css("opacity",0); //reset
            callback(); //next list
        });
        return;
    }

    $listItems.eq(index).animate({left:0, opacity:1}, 2500, function() {
        AnimateList($listItems, index+1, callback)
    });
}

function FadeLists($lists, index) {
    if (index >= $lists.length) index = 0;
    var $currentList = $lists.eq(index);
    $currentList.fadeIn(function() {
        AnimateList($currentList.find("li"), 0, function() { FadeLists($lists, index + 1) 
        });
    }) 
}

var $allLists = $("ul.contracts")
FadeLists($allLists, 0);

I've tried adding a setTimeout around "FadeLists" but it doesn't seem to work.

function FadeLists($lists, index) {
    if (index >= $lists.length) index = 0;
    var $currentList = $lists.eq(index);
    setTimeout($currentList.fadeIn(function() {
        AnimateList($currentList.find("li"), 0, function() { FadeLists($lists, index + 1), 2500); 
        });
    }) 
}

Neither did adding a time to the Fadelists argument.

setTimeout(FadeLists($allLists,0),2500);

How can I get it to keep each list visible for 2 seconds before running FadeLists again?

Per zero298 I tried the following, but it delays the initial run by the specified time and doesn't allow any delay between fading in the ul's

function AnimateList($listItems, index, callback) {
    if (index >= $listItems.length) {
        $listItems.closest("ul.contracts").fadeOut(function() {
            $listItems.css("left","400px").css("opacity",0); //reset
            callback(); //next list
        });
        return;
}

    $listItems.eq(index).animate({left:0, opacity:1}, 1500, function() {
        AnimateList($listItems, index+1, callback)
    });
}

function FadeLists($lists, index) {
    if (index >= $lists.length) index = 0;

    var $currentList = $lists.eq(index);
    setTimeout( () => $currentList.fadeIn(function() {
        AnimateList($currentList.find("li"), 0, function() {        
            FadeLists($lists, index + 1) });
    })); 
}

var $allLists = $("ul.contracts")
// FadeLists($allLists, 0);
setTimeout(() => FadeLists($allLists,0),2500);
Dirty Bird Design
  • 5,333
  • 13
  • 64
  • 121
  • 2
    Please add **how** you tried adding a `setTimeout`. I don't see that attempt in your code. – zero298 Dec 17 '19 at 19:22
  • `setTimeout` wants a function, you're giving a function that is already called. Try `setTimeout(() => FadeLists($allLists,0),2500);` and you'll need to adjust `FadeLists` in a similar fashion. – zero298 Dec 17 '19 at 19:28
  • setTimeout(() => FadeLists($allLists,0),2500); delays the first time it runs. Not sure I follow the rest. – Dirty Bird Design Dec 17 '19 at 19:34
  • You also need to delay the `setTimeout` within the `FadeLists` function, so `setTimeout(() => $currentList.fadeIn(function() {...})`. – zero298 Dec 17 '19 at 19:38
  • Updated code at end of question... still no luck. Im doing something wrong obviously – Dirty Bird Design Dec 17 '19 at 19:53
  • 1
    Does this answer your question? [how to add pause at end of function before moving on](https://stackoverflow.com/questions/59382574/how-to-add-pause-at-end-of-function-before-moving-on) – nurdyguy Dec 17 '19 at 22:53
  • Yeah, that was my second question after this was voted to be closed. – Dirty Bird Design Dec 17 '19 at 22:55

1 Answers1

1

Since you are changing the style, you should move as much code as possible to CSS. I made this code so the only CSS property that needs to be changed with JS is the animation delay, since there's no way of using the index in current CSS. This happens only once when the page is loaded, then no more JS running. All timing loops reside in the CSS keyframes.

$(".contracts li").each(function(index){
  $(this).css({'animation-delay' : (1+index)+'s'});
});
body {
  overflow-x: hidden;
}

li {
  position: relative;
  animation: fade 8s infinite;
}

@keyframes fade {
  0% { left: 400px; opacity: 0; }
  20%, 100% { left: 0; opacity: 1; }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>

<ul id="one" class="contracts">
  <li>one</li>
  <li>one</li>
  <li>one</li>
</ul>
<ul id="two" class="contracts">
  <li>two</li>
  <li>two</li>
  <li>two</li>
</ul>
rafaelcastrocouto
  • 11,781
  • 3
  • 38
  • 63