1

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);

1 Answer 1

1

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>

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that was what I was looking for! :)

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.