Javascript 在继续循环之前,每个函数都在等待函数完成
我实际上是在尝试循环遍历一组LI标记,并插入一些文本,以模拟某人编写一个要做的事情列表的样子。它可以工作,但它同时写入每个列表项,而不是等待。有没有一个简单的方法来实现这一点?我这里有一个JS fiddle设置:但是代码看起来像这样。谢谢Javascript 在继续循环之前,每个函数都在等待函数完成,javascript,jquery,Javascript,Jquery,我实际上是在尝试循环遍历一组LI标记,并插入一些文本,以模拟某人编写一个要做的事情列表的样子。它可以工作,但它同时写入每个列表项,而不是等待。有没有一个简单的方法来实现这一点?我这里有一个JS fiddle设置:但是代码看起来像这样。谢谢 function addListItems() { var str = { listitem1:'personal background check', listitem2:'look into my sketchy neighbor',
function addListItems() {
var str = {
listitem1:'personal background check',
listitem2:'look into my sketchy neighbor',
listitem3:'look up my driving record',
listitem4:'pick up milk',
listitem5:'wash the car'
}
$('.list-container li').each(function(){
var z = $(this).attr('id');
var str2 = str[z];
var delay = 0;
for (var i = 0; i <= str2.length; i++) {
(function(str2){
delay += 100 + Math.floor(Math.random()*11)*6;
setTimeout(function(){
appendStr(str2);
},delay);
})(str2[i])
}
function appendStr(str2) {
$('#'+ z).append(str2);
}
});
}
函数addListItems(){
var str={
清单项目1:“个人背景调查”,
列表项2:“看看我的粗略邻居”,
列表项3:“查看我的驾驶记录”,
列表项4:“拾起牛奶”,
清单项目5:“洗车”
}
$('.list container li')。每个(函数(){
var z=$(this.attr('id');
var str2=str[z];
var延迟=0;
对于(var i=0;i使延迟累积:
var str={
listitem1:'写入第一项',
listitem2:'写入第二项',
listitem3:'编写第三项',
listitem4:'编写第四项',
listitem5:'写第五项'
},累积显示=0;
$('.list container li')。每个(函数(){
var z=$(this.attr('id');
var str2=str[z];
var延迟=累积延迟;
对于(var i=0;i简化如何?使用两个变量在单个循环中迭代稍微修改的数据结构的全部内容。如下所示
var字符串=
[
{“id”:“listitem1”,“text”:“写入第一项”},
{“id”:“listitem2”,“text”:“写入第二项”},
{“id”:“listitem3”,“text”:“写入第三项”},
{“id”:“listitem4”,“text”:“写入第四项”},
{“id”:“listitem5”,“text”:“写入第五项”},
]
var-stringsIndex=0;
var textIndex=0;
AddString();
函数AddString(){
if(stringsIndex=strings[stringsIndex].text.length)
{
stringsIndex++;
if(stringsIndex==strings.length)
{
返回;
}
textIndex=0;
}
$(“#”+字符串[stringsIndex].id).append(字符串[stringsIndex].text[textIndex]);
textIndex++;
var延迟=10+数学下限(数学随机()*11)*6;
setTimeout(AddString,delay);
}
}
我将反转工作方式:
从要编写的字符串开始
对于每个字符串:
查找相应的列表项(按id)
用打字机的方式写出整个字符串
完成后调用下一个迭代
var strings = [
'personal background check',
'look into my sketchy neighbor',
'look up my driving record',
'pick up milk',
'wash the car'
];
function iterate(strings, idx)
{
if (idx >= strings.length) { return; }
var id = 'listitem' + (idx + 1),
el = document.getElementById(id);
typewriter(el, strings[idx], 0, function() {
iterate(strings, idx + 1);
});
}
function typewriter(el, str, idx, cb)
{
if (idx >= str.length) {
return cb();
}
setTimeout(function() {
el.innerText = str.substr(0, idx + 1);
typewriter(el, str, idx + 1, cb);
}, 100 + Math.floor(Math.random() * 11) * 6);
}
+1,这是一个写得很好的问题和JSFIDLE示例。我不确定这个问题的解决方案是什么,但我非常确定问题不是。each()
,而是您使用的setTimeout()
setTimeout()
是异步执行的,这意味着整个循环以迭代方式完成(并非同时),但完成得非常快,然后setTimeout
函数处理程序在循环完成后开始工作。我想了解一些关于如何使用deferred
链接这些函数的想法。我同意Snixtor的解释,并补充说,您可能应该根据您选择的列表项乘以延迟值重新启用(您可以使用each(函数(索引){…
获取索引)。第一项不需要额外延迟,但您可以将第二项延迟1秒,第三项延迟2秒,以此类推,这将产生每秒添加一个列表项的效果。按照审美学家的建议使用deferred
可能是一个更干净的解决方案。如果您想使用deferred,您还需要在键入时添加一个触发器ng已经完成了。这很容易做到,但最终你可能会有不太容易理解的代码。我建议你还是将其包装成插件式的模式。不需要额外的变量。只需将行var delay=0;
移到每个
之外即可获得相同的结果。谢谢Floyd.I我选择了Snixtor的解决方案,因为我比我原来的解决方案更喜欢它,但我对使用我现有的代码找到解决方案表示赞赏。感谢Snixtor。我最终选择了这个解决方案,因为它对我来说是最容易理解的,因为我必须在整个过程完成后添加回调,并在每次迭代后添加一些附加功能谢谢你,杰克。我最终选择了斯奈克斯特的解决方案,但你对它的理解也很好。
var strings =
[
{ "id":"listitem1", "text": "write the first item" },
{ "id":"listitem2", "text": "write the second item" },
{ "id":"listitem3", "text": "write the third item" },
{ "id":"listitem4", "text": "write the fourth item" },
{ "id":"listitem5", "text": "write the fifth item" },
]
var stringsIndex = 0;
var textIndex = 0;
AddString();
function AddString(){
if (stringsIndex < strings.length){
if (textIndex >= strings[stringsIndex].text.length)
{
stringsIndex++;
if (stringsIndex == strings.length)
{
return;
}
textIndex = 0;
}
$("#" + strings[stringsIndex].id).append(strings[stringsIndex].text[textIndex]);
textIndex++;
var delay = 10 + Math.floor(Math.random()*11)*6;
setTimeout(AddString, delay);
}
}
var strings = [
'personal background check',
'look into my sketchy neighbor',
'look up my driving record',
'pick up milk',
'wash the car'
];
function iterate(strings, idx)
{
if (idx >= strings.length) { return; }
var id = 'listitem' + (idx + 1),
el = document.getElementById(id);
typewriter(el, strings[idx], 0, function() {
iterate(strings, idx + 1);
});
}
function typewriter(el, str, idx, cb)
{
if (idx >= str.length) {
return cb();
}
setTimeout(function() {
el.innerText = str.substr(0, idx + 1);
typewriter(el, str, idx + 1, cb);
}, 100 + Math.floor(Math.random() * 11) * 6);
}