JSFiddle - React, Tailwind, and code Playground

by Kevin Pliester

HTML

<div class="tippen" data-text="Das ist ein Test!" data-speed="200" data-timeout="250">

</div>

<div class="height">

</div>

<div class="tippen" data-text="Das ist ein Test!" data-speed="200" data-timeout="250">

</div>

CSS

.height {
  height: 200vh;
}

JavaScript

(function($) {
  $.fn.isInViewport = function() {
    var element_top = $(this).offset().top;
    var element_bottom = element_top + $(this).outerHeight();
    var viewport_top = $(window).scrollTop();
    var viewport_bottom = viewport_top + $(window).height();
    return element_bottom > viewport_top && element_top < viewport_bottom;
  };

  function tippen(e, i) {
    let currentText = $(e).attr("data-text");
    let currentSpeed = $(e).attr("data-speed");
    let currentContent = $(e).text();

    if (i < currentText.length) {
      $(e).text(currentContent + currentText.charAt(i));
      i++;
      setTimeout(function() {
        tippen(e, i)
      }, currentSpeed);
    }
  }

  $(".tippen").each(function() {
    let i = 0;
    let currentItem = this;
    let timeout = 0;
    let seen = false;

    if ($(currentItem).attr("data-timeout").length) {
      timeout = $(currentItem).attr("data-timeout");
    }

    if (false === seen && $(currentItem).isInViewport()) {
      seen = true;
      setTimeout(function() {
        tippen(currentItem, i);
      }, timeout);
    }

    $(window).on("resize scroll", function() {
      if (false === seen && $(currentItem).isInViewport()) {
        seen = true;
        setTimeout(function() {
          tippen(currentItem, i);
        }, timeout);
      }
    });
  });
})(jQuery);