0

Using the answer to my previous question, I have been able to successfully create an "animated letter incrementer" for any given single string. Now I'd like to make the code more dynamic and have it work on any elements that have a specific class. The value of the "word" to use is set to whatever text falls inside the class.

Question:

How can I loop through each block class, grab the text inside it to use as the word, run the letter increment function and have them all increment on screen like the original question?

HTML:

<span class="block">Hi</span>
<span class="block">Hey there</span>
<span class="block">There There</span>

JS:

$(document).ready(function() {

    $('.block').each(function () {

        function Letter(table, letter, duration) {
            this.table = table;
            this.letter = letter;
            this.current = 0;
            this.delay = duration / tbl.indexOf(letter);   // ms
            this.time = Date.now();
            this.done = false;
        }
        Letter.prototype.update = function() {
            if (this.done) return;
            var time = Date.now();
            if (time - this.time >= this.delay) {
                this.time = time;
                if (this.letter === this.table[this.current] || this.current === this.table.length) {
                    this.done = true;
                } else {
                  this.current++;
                }
            }
        };

        var word = $(this).html();
        console.log ('Word: ' + word);

        var tbl = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        var letters = [];
        word.toUpperCase().split("").forEach(function(l) {
            letters.push(new Letter(tbl, l, 2500))
        });

        (function loop() {
            var txt = "", isDone = true;
            letters.forEach(function(l) {
            l.update();
            if (!l.done) isDone = false;
            txt += l.table[l.current];
        });

        // output txt
        $(this).html(txt);

        if (!isDone) requestAnimationFrame(loop);
        else { /* done */ }
        })();

    });

});

When I assign $(this).html(txt) at the end, it causes all of the text to disappear.

Original Snippet:

function Letter(table, letter, duration) {
  this.table = table;
  this.letter = letter;
  this.current = 0;
  this.delay = duration / tbl.indexOf(letter);   // ms
  this.time = Date.now();
  this.done = false;
}
Letter.prototype.update = function() {
  if (this.done) return;
  var time = Date.now();
  if (time - this.time >= this.delay) {
    this.time = time;
    if (this.letter === this.table[this.current] || 
        this.current === this.table.length) {
      this.done = true;
    }
    else {
      this.current++;
    }
  }
};

var word = "hello there";
var tbl = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var letters = [];
word.toUpperCase().split("").forEach(function(l) {
  letters.push(new Letter(tbl, l, 2500))
});

(function loop() {
  var txt = "", isDone = true;
  letters.forEach(function(l) {
    l.update();
    if (!l.done) isDone = false;
    txt += l.table[l.current];
  });

  // output txt
  d.innerHTML = txt;
  
  if (!isDone) requestAnimationFrame(loop);
  else { /* done */ }
})();
<!DOCTYPE html>
<html>
<head>
    <style>
        #d {font:bold 32px monospace}
    </style>
    <script src="/scripts/snippet-javascript-console.min.js"></script>
</head>
<body>
    <div id=d></div>
</body>
</html>
Community
  • 1
  • 1
cpcdev
  • 1,130
  • 3
  • 18
  • 45
  • What is an example input and expected output – Richard Hamilton Jun 18 '16 at 16:57
  • Note that, in the code you've posted, you've missed the leading `$` from the `$(document).ready(...)`; this isn't the problem, though, just an aside in the copy/paste. – David Thomas Jun 18 '16 at 16:58
  • If you run the snippet in the original question, you'll see how it works. But I want to modify the code to apply this "letter incrementer" effect to any element that contains a specific class. – cpcdev Jun 18 '16 at 16:59
  • You should, really, make this question self-contained (though keep the reference to the other question for contextual purposes) and include a snippet in *this* question, rather than expecting us to elsewhere to run your code; also further (appropriate) indentation would be useful too. – David Thomas Jun 18 '16 at 17:01
  • Done, and sorry.. still learning the ways. – cpcdev Jun 18 '16 at 17:05

0 Answers0