为什么最后一个字符反复打印?

时间:2018-07-30 11:08:43

标签: javascript jquery html

我编写了以下内容以使div中的文本动画化,但是我找不到如何重复打印最后一个字符。

var textClass = $(".first-text");
var text = textClass.text();
textClass.text("");
for (var i in text) {
  $(textClass).animate({
    opacity: 0.25
  }, 200, function() {
    $(textClass).append(text.charAt(i));
  });
}
p:not(:first-child) {
  display: none;
}

p {
  margin: 0 auto;
  font-size: 24px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="animate-text">
  <p class="first-text">HTML</p><br>
</div>

如果我尝试提醒itext.charAt(i)的值,我总是会得到所需的输出,但是当我尝试在div中附加相同的值时,我总是会得到相同的最后一个字母重复打印。我找不到我误会的地方。我找不到逻辑中的错误。

如果有人能启发我理解以上代码中的错误,我将很高兴听到它。

Here是我尝试此代码的小提琴的链接。

谢谢。

4 个答案:

答案 0 :(得分:8)

关于闭包,您已经陷入一些学习中。当i循环并最终在函数中运行时,它仅查看最后一个字符,因为在第一个i实际触发之前,animate()被覆盖了。

您可以通过自己手动创建一个闭包,将其包装在函数中并传递它,以在循环时保留变量来抵消这种情况。

有关闭包的更多信息,请查看:What is a 'Closure'?

var textClass = $(".first-text");
var text = textClass.text();
textClass.text("");
for (var i in text) {
  (function (char) {
    $(textClass).animate({
      opacity: 0.25
    }, 200, function() {
      $(textClass).append(text.charAt(char));
    });
  })(i)
}
p:not(:first-child) {
  display: none;
}

p {
  margin: 0 auto;
  font-size: 24px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="animate-text">
  <p class="first-text">HTML</p><br>
</div>

或者,您可以使用新的letconst语法,它们为块的范围定义i(实际上是在if块周围创建一个闭包。)

var textClass = $(".first-text");
var text = textClass.text();
textClass.text("");
for (const i in text) {
  $(textClass).animate({
    opacity: 0.25
  }, 200, function() {
    $(textClass).append(text.charAt(i));
  });
}
p:not(:first-child) {
  display: none;
}

p {
  margin: 0 auto;
  font-size: 24px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="animate-text">
  <p class="first-text">HTML</p><br>
</div>

答案 1 :(得分:2)

您可以创建闭包,也可以使用.loc[]letconst循环内声明变量i,该变量将保留for的当前值在每次迭代中:

i
var textClass = $(".first-text");
var text = textClass.text();
textClass.text("");
for (const i in text) {
  $(textClass).animate({
    opacity: 0.25
  }, 200, function() {
    $(textClass).append(text.charAt(i));
  });
}
p:not(:first-child) {
  display: none;
}

p {
  margin: 0 auto;
  font-size: 24px;
}

答案 2 :(得分:1)

使用letconst而不是var,您可以获得更好的范围,并且不需要创建闭包。也无需继续执行$(textClass)-您可以缓存对象

const $textClass = $(".first-text");
const text = $textClass.text();
$textClass.text("");
for (let i in text) {
  $textClass.animate({
    opacity: 0.25
  }, 200, function() {
     $textClass.append(text.charAt(i));
  });
}
p:not(:first-child) {
  display: none;
}

p {
  margin: 0 auto;
  font-size: 24px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="animate-text">
  <p class="first-text">HTML</p><br>
</div>

答案 3 :(得分:1)

您的脚本中似乎有一个变量声明。

var textClass = $(".first-text");
var text = textClass.text();
textClass.text("");
for (const i in text){
  $(textClass).animate({
    opacity: 0.25
  }, 200, function(){
    $(textClass).append(text.charAt(i));
  });
}

请查看以下JSFiddle链接。 http://jsfiddle.net/tp3juw54/19/