2017-05-13 46 views
0

我不知道我在哪里出错了这段代码。单击事件处理程序中的SetInterval方法

我在寻找:

选项卡的列表上点击该动画开始时并再次点击它,它停止。我打算用setInterval来做(只是为了练习)。

下面是我想使用的代码:

function writeMe() { 
    var p = document.createElement("p"); 
    p.innerHTML = "List 1"; 
    var ilu = document.getElementById("ilu"); 
    ilu.appendChild(p); 
     if (ilu.getElementsByTagName("p").length === 5) { 
      ilu.innerHTML = ""; 
     } 
} 
    var li = document.getElementsByTagName("li"); 
    for(i=0;i<li.length;i++) { 
     li[i].addEventListener("click", function(e) { 
      if (this.style.backgroundColor == "yellow") { 
       this.style.backgroundColor = ""; 
       clearInterval(writeMe); 
      } else { 
       for(i=0;i<li.length;i++) { 
        li[i].style.backgroundColor = ""; 
       } 
       this.style.backgroundColor = "yellow"; 
       var writeMe = setInterval(writeMe, 1000); 
       writeMe(); 
       } 
     e.stopPropagation(); 
     }); 
    } 

我的逻辑是:

For循环设置在每个李时珍的点击情况。现在,当他们被点击时,他们会调用setInterval函数,当再次点击时,他们会停止它。

我哪里错了?谢谢。

+0

当您在事件侦听器中分配相同的变量名时,'writeMe'不是一个函数。这是计时器ID。浏览器控制台应该看到错误,告诉你它不是一个函数 – charlietfl

+0

谢谢。我将变量名称writeMe更改为tellMe。这里是[JSBin](http://jsbin.com/jibitil)。我现在面临的两个问题是:'clearInterval()无法正常工作,并且随着我一直点击这些标签,'动画正在加速'! – SamC

+0

@SamC,检查[我的答案](http://stackoverflow.com/a/43953682/2545680) –

回答

0

有你的方法有几个问题:

  • 在原来的问题,你有一个名为writeMe的函数,你是压倒我当你设置时间间隔var writeMe = setInterval(writeMe, 1000);时,你的范围。但是你也在评论中提到你改名为tellMe本应该解决这个冲突。
  • 在你JSBin
    • 您要使用循环i的指数值。您需要了解变量范围和关闭。点击发生在循环结束很长时间后,无论您点击哪个元素,i的值可能始终保持在5(在此特定情况下)。
    • 声明多个writeMe方法如writeMe2, writeMe3...不是解决方案。你必须添加另一个writeMe方法,除了可能有1或2个值更改外,其他方法与其他方法完全相同。
    • 在循环内多次使用i,但不会将其声明为局部变量,其值为var。你正在将上层变量映射到闭包范围中。虽然它不会影响您的使用案例(尚未),但它将使代码在未来保持开放。

请尝试使用以下代码片段。

(function() { 
 
    "use strict"; 
 

 
    function writeMe(index) { 
 
     window.console.log('List ' + (index + 1)); 
 
    } 
 

 
    function getClickHandler(index, listItems) { 
 
     return function (event) { 
 
      event.stopPropagation(); 
 

 
      if (intervalTimerId) { 
 
       window.clearInterval(intervalTimerId); 
 
      } 
 

 
      if (this.style.backgroundColor == "yellow") { 
 
       this.style.backgroundColor = ""; 
 
       return; 
 
      } 
 

 
      // clear bg-color for all list-items 
 
      for (var i = 0; i < listItems.length; i++) { 
 
       listItems[i].style.backgroundColor = ""; 
 
      } 
 

 
      this.style.backgroundColor = "yellow"; 
 

 
      intervalTimerId = setInterval(function() { 
 
       writeMe(index); 
 
      }, 1000); 
 

 
      writeMe(index); 
 
     }; 
 
    } 
 

 
    var listItems = document.getElementsByTagName("li"), 
 
     intervalTimerId = null; 
 

 
    for (var i = 0; i < listItems.length; i++) { 
 
     listItems[i].addEventListener("click", getClickHandler(i, listItems)); 
 
    } 
 
})();

我故意冷落这是您根据您的要求实现功能的实际肉。如果您希望在我的代码中看到控制台日志,请不要忘记在您正在测试的浏览器中打开开发工具控制台。

+0

是的,我认为你是对的。从编码的角度来看,以后需要添加多个功能从来都不是一个好主张。是的,“我”正在返回5.我在[JSBin](http://jsbin.com/jibitil)中进行了更改。你可以看看它吗?唯一的问题是它不会忘记以前的setInterval。因此,除非我先在前一个标签上清除间隔,然后再单击下一个标签,否则它会运行之前的点击次数的setInterval以及下一次点击的setInterval。 – SamC

+0

@SamC你没有用我的例子更新JSBin。 ''intervalTimerId'(或者你的情况下的'tellMe')需要在点击处理程序之外声明(带'var')。 –

+0

是的,忘记了在最后的评论中提及。我试图弄清楚你的代码的含义。我的意思是逻辑。首先,你为什么将intervalTimerId设置为null?其次,我看到您正在分隔范围,以便事件回调不会绑定到“i”的值,因此,每个“li”都会为其自身获取单独的索引参数。但是,我的代码中的“let”声明不是做同样的事情吗?我也尝试将if(intervalTimerId){clearInterval();}更改为我的代码,但它仍然不起作用。你能解释一下吗? – SamC

0

这就是你可能在寻找:

// group all functions so that we can call the one 
    // corresponding to the clicked tab 
    var fns = [writeMe, writeMe1, writeMe2, writeMe3]; 

    var tellMe = null; 
    var li = document.getElementsByTagName("li"); 

    // need to use `let` here to avoid IIFE 
    for (let i = 0; i < li.length; i++) { 
     li[i].addEventListener("click", function (e) { 
      clearInterval(tellMe); 
      for (let j = 0; j < li.length; j++) { 
       li[j].style.backgroundColor = ""; 
      } 
      this.style.backgroundColor = "yellow"; 
      tellMe = setInterval(fns[i], 1000); 
      e.stopPropagation(); 
     }); 
    } 

<!DOCTYPE html> 
 
<html> 
 
<head> 
 
    <meta charset="utf-8"> 
 
    <meta name="viewport" content="width=device-width"> 
 
    <title>JS Bin</title> 
 
<style> 
 
\t .web_image { 
 
\t \t display: block; 
 
\t \t text-align:center; 
 
\t } 
 
\t .next_image { 
 
\t \t display: none; 
 
\t \t text-align:center; 
 
\t } 
 
\t ul { 
 
\t \t background-color: #a9b9c9; 
 
\t \t text-align:left; 
 
\t \t margin:0; 
 
\t \t padding:0; 
 
\t } 
 
\t li { 
 
\t \t list-style-type:none; 
 
\t \t display:inline-block; 
 
\t \t padding:20px; 
 
\t \t border:1px solid red; 
 
\t } 
 
</style> 
 
</head> 
 
<body> 
 
\t <h1 class="abc def ghi jkl">Header 1</h1> 
 
\t <p id="som_thng">Restatis igitur vos; Ille enim occurrentia nescio quae comminiscebatur;</p> 
 
\t <div class="web_image"><img src="http://placehold.it/350x150" /> \t </div> 
 
\t <div class="next_image"><img width="350px" src="http://img06.deviantart.net/1b60/i/2013/225/5/6/shiva_by_christasvengel-d6hyf9n.jpg" /> \t </div> 
 
\t 
 
\t <ul> 
 
\t \t <li>List 1</li> 
 
\t \t <li>List 2</li> 
 
\t \t <li>List 3</li> 
 
\t \t <li>List 4</li> 
 
\t \t <li>List 5</li> 
 
\t </ul> 
 
\t \t <div id="ilu"></div> 
 
<script> 
 
\t (function() { 
 
\t \t //var writeMe1 = setInterval(writeMe1, 1000); 
 
\t \t //var writeMe2 = setInterval(writeMe2, 1000); 
 
\t \t //var writeMe3 = setInterval(writeMe3, 1000); 
 
    function writeMe1() { 
 
\t  var p = document.createElement("p"); 
 
\t  p.innerHTML = "List 1."; 
 
\t  var ilu = document.getElementById("ilu"); 
 
\t \t \t \t \t ilu.appendChild(p); 
 
\t  if (ilu.getElementsByTagName("p").length === 5) { 
 
    \t  ilu.innerHTML = ""; 
 
    \t } 
 
    } 
 
\t \t function writeMe2() { 
 
\t  var p = document.createElement("p"); 
 
\t  p.innerHTML = "List 2."; 
 
\t  var ilu = document.getElementById("ilu"); 
 
\t \t \t \t \t ilu.appendChild(p); 
 
\t  if (ilu.getElementsByTagName("p").length === 5) { 
 
    \t  ilu.innerHTML = ""; 
 
    \t } 
 
    } 
 
\t \t function writeMe3() { 
 
\t  var p = document.createElement("p"); 
 
\t  p.innerHTML = "List 3."; 
 
\t  var ilu = document.getElementById("ilu"); 
 
\t \t \t \t \t ilu.appendChild(p); 
 
\t  if (ilu.getElementsByTagName("p").length === 5) { 
 
    \t  ilu.innerHTML = ""; 
 
    \t } 
 
    } 
 
\t \t function writeMe() { 
 
\t \t \t \t \t var p = document.createElement("p"); 
 
\t \t \t \t \t p.innerHTML = "List 1"; 
 
\t \t \t \t \t var ilu = document.getElementById("ilu"); 
 
\t \t \t \t \t ilu.appendChild(p); 
 
\t \t \t \t \t if (ilu.getElementsByTagName("p").length === 5) { 
 
\t \t \t \t \t \t \t \t \t ilu.innerHTML = ""; 
 
\t \t \t } 
 
\t \t } 
 
     
 
     
 
    // group all functions so that we can call the one 
 
    // corresponding to the clicked tab 
 
    var fns = [writeMe, writeMe1, writeMe2, writeMe3]; 
 

 
    var tellMe = null; 
 
    var li = document.getElementsByTagName("li"); 
 

 
    // need to use `let` here to avoid IIFE 
 
    for (let i = 0; i < li.length; i++) { 
 
     li[i].addEventListener("click", function (e) { 
 
      clearInterval(tellMe); 
 
      for (let j = 0; j < li.length; j++) { 
 
       li[j].style.backgroundColor = ""; 
 
      } 
 
      this.style.backgroundColor = "yellow"; 
 
      tellMe = setInterval(fns[i], 1000); 
 
      e.stopPropagation(); 
 
     }); 
 
    } 
 
     
 
\t \t var div = document.querySelectorAll("div"); 
 
\t \t div[0].addEventListener("click", function(e) { 
 
\t \t \t div[0].style.display = "none"; 
 
\t \t \t div[1].style.display = "block"; 
 
\t \t \t e.stopPropagation(); 
 
\t \t }); 
 
\t \t div[1].addEventListener("click", function(e) { 
 
\t \t \t div[1].style.display = "none"; 
 
\t \t \t div[0].style.display = "block"; 
 
\t \t \t e.stopPropagation(); 
 
\t \t }); 
 
\t })(); 
 
</script> 
 
</body> 
 
</html>

相关问题