我正在尝试编写一个javascript程序,它在单击按钮时将输入元素的值存储在数组中。数组是拆分,每个单独的字母添加到span元素,然后附加到文档。我们的想法是使用setTimeout创建一个打字效果。
我遇到了在循环中创建闭包的问题,所以当前setTimeout函数总是返回迭代的最终值。
有问题的函数位于代码块的底部,名为addTextToBoard();
var noteButton = document.querySelector('[data-js="button"]');
noteButton.addEventListener("click",function() {
var messageIn = document.querySelector('[data-js="input"]');
var message = messageIn.value;
postToBoard(message);
});
function postToBoard(val) {
var noteBoard = document.querySelector('[data-js="noteboard"]');
var newElement = document.createElement('div');
newElement.classList.add('noteboard__item');
noteBoard.appendChild(newElement);
setTimeout(function(){
newElement.classList.add('active');
}, 200);
addTextToBoard(newElement, val);
}
function addTextToBoard(el, val) {
var wordArray = val.split('');
for(i = 0; i < wordArray.length; i++) {
var letter = document.createElement('span');
letter.innerHTML = wordArray[i];
setTimeout(function(x){
return function() {}
el.appendChild(letter);
}(i),1000);
}
}
我相信我很接近,我只是不完全理解创建闭包的语法。如果有人能够向正确的方向发出捅,而不必给出完整的解决方案。
我基本上试图粘贴here中的以下代码片段,但我一直错过了一些东西!
setTimeout(function(x) { return function() { console.log(x); }; }(i), 1000*i);
最佳,
杰克
答案 0 :(得分:1)
你很亲密。
由于“字母”变量发生变化,您只会反复添加最后一个字母。你需要在setTimeout()
回调函数上“保存”当前的字母,一种方法是这样的:
function appendMyLetter(letter) {
return(function() {
el.append.Child(letter);
});
}
function addTextToBoard(el, val) {
var wordArray = val.split('');
for(i = 0; i < wordArray.length; i++) {
var letter = document.createElement('span');
letter.innerHTML = wordArray[i];
setTimeout(appendMyLetter(letter), 1000);
}
}
这样,appendMyLetter()
函数将使用不同的参数(每个字母一个)调用,并返回一个函数,其中包含要由setTimeout()
调用的正确“存储”值。
密切关注您的setTimeout()
代码
setTimeout(function(x){
return function() {}
el.appendChild(letter);
}(i),1000);
如果您使用了正确的参数并在返回的函数中使用appendChild()
,它会正常工作,如下所示:
setTimeout(function(x){
return(function() {
el.appendChild(x);
});
}(letter),1000);
答案 1 :(得分:0)
您可以创建一个立即调用的函数表达式IIFE来创建一个闭包
# make install
答案 2 :(得分:0)
我不知道这是否有效,但是你在这里稍微改变了一下:
letter.innerHTML += wordArray[i];
如果你没有达到你想象的效果,你会更好地尝试通过我这样增加计时器
setTimeout(function(){
...
},1000*i);