使用每个函数访问此 Class

Access This Class using Each Function

我有一些代码可以递增给定单词的每个字母,从 A 开始直到到达目标字母。您可以在下面的代码片段中看到示例。当我以单个 div id 为目标时,该代码有效,但我想这样做,以便它将这种递增的文本效果应用于分配给它的 "block" class 的每个文本块。

$(document).ready(function() {

  console.log("ready!");

  $('.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))
      console.log(l);
    });

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

      // output txt
      //$("div#d").html(txt);
      $(this).parent('.block').html(txt);

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

  });

});

我正在尝试将递增效果输出到分配给它的 "block" class 的每个文本位:

$(this).parent('.block').html(txt);

我正在尝试使用上面的代码行针对每个 "block" class 但它不起作用。我该怎么做?

注意这一行 "Word" 递增是 "block" 标签内的内容:

var word = $(this).html();

$(document).ready(function() {

  console.log("ready!");

  $('.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))
      console.log(l);
    });

    (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;
      $("div#d").html(txt);

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

  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=d></div>

<div id="other_spans">
  <span class="block">First</span>
  <span class="block">Second</span>
  <span class="block">Third</span>

在您的代码中,IIFE 中的 this 是 window 对象。使用块 class 保留元素的引用,并在 IIFE 中使用它。如下所示 -

  $(document).ready(function() {

    console.log("ready!");
    var tbl = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    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++;
            }
        }
    };


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

        var $this = $(this);

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


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

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

            // output txt
            //$("div#d").html(txt);
            $this.html(txt);

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

    });
});

这是工作中的 link fiddle https://jsfiddle.net/HectorBarbossa/tg9hpk4a/

您可以将 Letter 函数和 tbl 变量移到 .each() 之外,以防止在元素的每次迭代中重新定义函数、变量;创建对 $(this) 当前元素的引用,在 loop

中使用引用

$(document).ready(function() {

  console.log("ready!");

  var tbl = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  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++;
      }
    }
  };

  $(".block").each(function() {
    // store reference to current `this` element
    var elem = $(this);
    var word = elem.html();
    console.log("Word: " + word);
    var letters = [];

    word.toUpperCase().split("")
    .forEach(function(l) {
      letters.push(new Letter(tbl, l, 2500))
      console.log(l);
    });

    (function loop() {
      var txt = "",
        isDone = true;
      letters.forEach(function(l) {
        l.update();
        if (!l.done) isDone = false;
        txt += l.table[l.current];
      });
      // `elem` : `this` element at `.each()` iteration
      elem.html(txt);

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

  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div id="d"></div>

<div id="other_spans">
  <span class="block">First</span>
  <span class="block">Second</span>
  <span class="block">Third</span>