在for循环

时间:2016-06-18 12:08:03

标签: javascript jquery closures frontend

我正在尝试编写一个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);

最佳,

杰克

3 个答案:

答案 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);