我做了一个小脚本练习,似乎我的循环和他们的超时有问题。 这是我的脚本的链接:http://codepen.io/JulienBarreira/pen/EWNoxJ
有时,当一个单词写作时,一两个字母就错了。例如,我没有“芝士汉堡”,而是“chkesebxrger”。
我发现了一个小技巧,所以它失败了,但我根本不知道为什么。
function charsAnim(i, word, j) {
setTimeout(function() {
var count = j;
if (j < steps) {
randomChar(i, word, count, j);
} else {
goodChar(i, word, count, j);
}
/* seems it fails less if I divide j, don't know why */
}, (speed/steps)*(j / 1.8));
}
当其他脚本在计算机上运行时(例如在我的个人资料页面中),问题会更频繁地出现。
即使不是我的问题,也请随时向我提供有关我的代码的任何建议。可能有一种更简单的方法来做同样的事情,我在这里进步。
谢谢:)
编辑:我在一个代码段中添加了3个iframe来向您显示问题,当您启动代码段时,第一个单词大部分时间都会失败。
var words = [
'unicorn',
'cheeseburger',
'pizza',
'pineapple',
'popsicle',
'bubbles',
'seagull',
'doodle',
'goggles',
'artichoke',
'potato',
'carrot',
'vegeta'
];
var letters = "abcdefghijklmnopqrstuvwxyz#%&^+=-";
var speed = 250;
var steps = 4;
function getRandomWord() {
var randomWord = words[Math.floor(Math.random() * words.length)];
return randomWord;
}
function getRandomLetter() {
var randomLetter = letters[Math.floor(Math.random() * letters.length)];
return randomLetter;
}
function randomWordLoop() {
var word = getRandomWord();
var textLength = word.length;
for(i = 0; i < textLength; i++) {
letterAppear(i, word);
}
function letterAppear(i, word) {
setTimeout(function() {
randomLetters(i, word);
}, speed*i);
}
function randomLetters(i, word) {
for (j = 0; j <= steps; j++) {
charsAnim(i, word, j);
}
}
function charsAnim(i, word, j) {
setTimeout(function() {
var count = j;
if (j < steps) {
randomChar(i, word, count, j);
} else {
goodChar(i, word, count, j);
}
/* seems it fails less if I divide j, don't know why */
}, (speed/steps)*(j / 1.8));
}
function randomChar(i, word, count, j) {
var letter = getRandomLetter();
if (j > 0) {
var oldText = $('#loader').text().slice(0, -1);
} else {
var oldText = $('#loader').text();
}
$('#loader').text(oldText + letter);
}
function goodChar(i, word, count, j) {
var oldText = $('#loader').text().slice(0, -1);
$('#loader').text(oldText + word[i]);
if (i == textLength - 1 ) {
removeWord();
}
}
function removeWord() {
setTimeout(function() {
for (k = 0; k < textLength; k++) {
removeLetters(k);
}
}, speed*2);
}
function removeLetters(k) {
setTimeout(function() {
removeLetter(k);
}, 75*k);
}
function removeLetter(k) {
var actualText = $('#loader').text().slice(0, -1);
$('#loader').text(actualText);
if (k == textLength - 1) {
randomWordLoop();
}
}
}
randomWordLoop();
body {
background-color: #010101;
}
.loader {
width: 300px;
color: #0c9c73;
text-align: left;
font-size: 50px;
font-family: Roboto Mono;
font-weight: 700;
text-transform: uppercase;
}
.loader:after {
content:'_';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<div class="loader" id="loader"></div>
<iframe width="560" height="315" src="https://www.youtube.com/embed/GquEnoqZAK0?autoplay=1" frameborder="0" allowfullscreen></iframe>
<iframe width="560" height="315" src="https://www.youtube.com/embed/GquEnoqZAK0?autoplay=1" frameborder="0" allowfullscreen></iframe>
<iframe width="560" height="315" src="https://www.youtube.com/embed/GquEnoqZAK0?autoplay=1" frameborder="0" allowfullscreen></iframe>
答案 0 :(得分:1)
您正在randomWordLoop()
for(i = 0; i < textLength; i++) {
letterAppear(i, word);
}
... setTimeout()
位于letterAppear()
内。基本上,当letterAppear()
在letterAppear
内执行时,i
变量不再具有与设置超时时相同的值。它具有全局值,可能已被页面中可能使用i
的任何其他函数设置为完全不同的值。
另请注意,设置for的正确方法不是全局使用i
,而是将其设置为函数的局部变量:for(var i = 0; i < textLength; i++) {...}
。
你无法正确看到它,因为你的函数会输出随机字母,并且没有任何视觉线索让你知道它运行在i
的错误值上,但我相信你的功能在大多数情况下是错误的。
要解决此问题,您需要letterAppear()
中的一个闭包,它会将i
和word
的正确值传递给setTimeout()
内的randomLetters()
,无论如何setTimeout()
的内容执行时的全局值:
for(var i = 0; i < textLength; i++) {
(function(i,word){
letterAppear(i, word);
})(i,word)
}
仔细观察代码,您可能需要在多个位置进行闭包(如果在代码执行时传递给函数的值非常重要),您还应该定义for
迭代器( i
和j
}在本地,使用var
,就像我上面所做的那样。
永远不要忘记你最好的JavaScript
朋友:
console.log(this, arguments);