Alexandre Buxo
Alexandre Buxo

Reputation: 45

Execute some JS after function with recursion

I'm having a problem executing a piece of js after a function with recursion. I tried so many ways, I can't figure how this can be done. I imagine it must be pretty simple.

This is what i what to execute after the recursion:

$(next).animate({"top": "0px", "opacity": "1"}, wordPause, "swing");

JS:

/* ANIMATION USE 
    <div class='wa-parent'>
        <p class='wa-child'>Line 1.</p>
        <p class='wa-child'>Line 2.</p>
    </div>
    <div class='wa-next'></div>
  */
  (function($) {
    var parent = "[wa-parent]";
    var child = "[wa-child]";
    var next = "[wa-next]";
    var parent_child = parent + " " + child;
    var linePause = 1000;
    var wordPause = 175;
    //var slidePause = 8000;

    //this will execute on load
    $(next).css("top", "7.5px").css("opacity", "0");
    $(parent_child).each(function () {
      var words = $(this).html().split(' ');
      $(this).html('').fadeTo(1, 0);
      for (var i = 0; i < words.length; i++) {
        $(this).append($('<span></span>')
                       .text(words[i] + (i + 1 == words.length ? '' : ' '))
                       .fadeTo(1, 0));
      }
    });

    function slideShow(slider) {
      //reset to hidden
      slider.find(parent).fadeTo(1, 0).find('span').fadeTo(1, 0);
      (function showNextSlide(slide) {
        slide.eq(0).fadeTo(500, 1, function () {
          (function showNextLine(line) {
            line.eq(0).fadeTo(500, 1, function () {
              (function showNextWord(word) {
                word.eq(0).css("top", "7.5px").css("opacity", "0").animate({"top": "0px", "opacity": "1"}, wordPause, "swing", function () {
                  (word = word.slice(1)).length && showNextWord(word);
                });

              })(line.eq(0).find('span'));
            })
              .delay(linePause)
              .queue(function () {
              (line = line.slice(1)).length && showNextLine(line);
              $(this).dequeue();
            });
          })(slide.eq(0).find(child));
        })
        
      })(slider.find(parent))
    }
    slideShow($("*"));
  })(jQuery);

Upvotes: 1

Views: 65

Answers (1)

aleksxor
aleksxor

Reputation: 8340

I believe adding condition to check whether the cycle is over and calling the callback after that should do:

word.eq(0)
    .css("top", "7.5px")
    .css("opacity", "0")
    .animate(
        { "top": "0px", "opacity": "1" }, 
        wordPause, 
        "swing", 
        function () {
            (word = word.slice(1)).length && showNextWord(word);
            if (line.length === 0 && word.length ===0) cb();
        }
    )

(function($) {
    var parent = ".wa-parent";
    var child = ".wa-child";
    var next = ".wa-next";
    var parent_child = parent + " " + child;
    var linePause = 1000;
    var wordPause = 175;

    $(next).css("top", "7.5px").css("opacity", "0");
    $(parent_child).each(function () {
      var words = $(this).html().split(' ');
      $(this).html('').fadeTo(1, 0);
      for (var i = 0; i < words.length; i++) {
        $(this).append($('<span></span>')
                       .text(words[i] + (i + 1 == words.length ? '' : ' '))
                       .fadeTo(1, 0));
      }
    });

    function slideShow(slider, cb) {
      //reset to hidden
      slider.find(parent).fadeTo(1, 0).find('span').fadeTo(1, 0);
      (function showNextSlide(slide) {
        slide.eq(0).fadeTo(500, 1, function () {
          (function showNextLine(line) {
            line.eq(0).fadeTo(500, 1, function () {
              (function showNextWord(word) {
                word.eq(0).css("top", "7.5px").css("opacity", "0").animate({"top": "0px", "opacity": "1"}, wordPause, "swing", function () {
                  (word = word.slice(1)).length && showNextWord(word);
                  if (line.length === 0 && word.length ===0) cb();
                })
              })(line.eq(0).find('span'));
            })
            .delay(linePause)
            .queue(function () {
              (line = line.slice(1)).length && showNextLine(line);
              $(this).dequeue();
            })
          })(slide.eq(0).find(child));
        })
      })(slider.find(parent))
    }
    slideShow($("*"), () => $(next).animate({"top": "0px", "opacity": "1"}, wordPause, "swing"));
  })(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wa-parent'>
  <p class='wa-child'>Line 1. something is typed here and then animated</p>
  <p class='wa-child'>Line 2. something is typed here and then animated</p>
</div>
<div class='wa-next'>and finally finished</div>

Upvotes: 1

Related Questions