2017-05-13 8 views
0

Ich weiß nicht, wo ich mit diesem Code falsch liege.SetInterval-Methode in einem Click-Event-Handler

Was ich suche:

Eine Liste von Registerkarten, auf dem eine Animation beginnt zu klicken und auf wieder klicken, stoppt er. Ich beabsichtige es mit setInterval (nur zum Üben).

Hier ist der Code, den ich zu verwenden Ich versuche:

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(); 
     }); 
    } 

Meine Logik ist:

Die For-Schleife die Klick Bedingungen auf jedem der Li setzt. Wenn sie jetzt angeklickt werden, rufen sie die setInterval-Funktion auf und wenn sie erneut geklickt wird, stoppen sie sie.

Wohin gehe ich falsch? Vielen Dank.

+0

'writeMe' ist keine Funktion, wenn Sie den gleichen Variablennamen im Ereignis-Listener zuweisen. Es ist die Timer-ID. Sollte in der Browser-Konsole ein Fehler angezeigt werden, der besagt, dass es keine Funktion ist – charlietfl

+0

Danke. Ich habe den Variablennamen writeMe in tellMe geändert. Hier ist die [JSBin] (http://jsbin.com/jibitil). Zwei Probleme, denen ich jetzt gegenüberstehe: 'clearInterval() funktioniert nicht' und während ich weiter auf die Tabs klicke, beschleunigt sich die' Animation'! – SamC

+0

@SamC, überprüfen Sie [meine Antwort] (http://Stackoverflow.com/a/43953682/2545680) –

Antwort

0

Es gibt ein paar Probleme mit Ihrem Ansatz:

  • In der ursprünglichen Frage, die Sie hatte eine Funktion namens writeMe, die Sie überschrieb ich n Ihrem Umfang, wenn Sie das Intervall var writeMe = setInterval(writeMe, 1000); festlegen. Aber du hast auch in einem Kommentar erwähnt, dass du das in tellMe umbenannt hast, was diesen Konflikt hätte lösen sollen.
  • In Ihrem JSBin:
    • Sie versuchen, den Index der Schleife i als Wert zu verwenden. Sie müssen variable Bereiche und Schließungen verstehen. Die Klicks erfolgen lange nach dem Ende der Schleife und der Wert i bleibt immer auf 5 (in diesem Fall), egal auf welches Element Sie klicken.
    • deklarieren mehrere writeMe Methoden wie writeMe2, writeMe3... ist NICHT die Lösung. Sie müssten eine weitere writeMe-Methode hinzufügen, die dasselbe wie die anderen tut, außer vielleicht 1 oder 2 Wertänderungen.
    • Verwenden Sie i mehrfach innerhalb der Schleife, ohne es als lokale Variable mit var zu deklarieren. Sie überschirmen die Variable mit dem oberen Bereich im Abschlussbereich. Obwohl es Ihren Anwendungsfall (noch) nicht beeinflusst, wird der Code in Zukunft für Probleme offen gehalten.

Versuchen Sie, die folgenden Ausschnitt verwenden.

(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)); 
 
    } 
 
})();

Ich habe die eigentliche Fleisch der Funktionalität absichtlich weggelassen, die für Sie nach Ihren Anforderungen zu implementieren ist.Wenn Sie die Konsolenprotokolle in meinem Code sehen möchten, vergessen Sie nicht, die Developer Tools-Konsole in dem Browser zu öffnen, den Sie gerade testen.

+0

Ja, ich denke, Sie haben Recht. Spätere Funktionen hinzufügen zu müssen, ist aus Codierungssicht nie eine gute Sache. Ja, das "i" kam zurück 5. Ich habe eine Änderung in [JSBin] (http://jsbin.com/jibitil) vorgenommen. Kannst du bitte hineinsehen? Das einzige Problem ist, dass das vorherige setInterval NICHT vergessen wird. Daher wird setInterval des vorherigen Klicks zusammen mit dem setInterval des nächsten Klicks ausgeführt, es sei denn, ich lösche zuerst auf der vorherigen Registerkarte clearInterval und klicke dann auf die nächste Registerkarte. – SamC

+0

@SamC Sie haben die JSBin nicht mit meinem Beispiel aktualisiert. 'intervalTimerId' (oder' tellMe' in Ihrem Fall) muss außerhalb des Click-Handlers deklariert werden (mit 'var'). –

+0

Ja, vergaß im letzten Kommentar zu erwähnen. Ich versuche herauszufinden, was dein Code bedeutet. Die Logik, meine ich. Erstens, warum setzen Sie intervalTimerId auf null? Zweitens sehe ich, dass Sie die Bereiche trennen, so dass der Event-Callback nicht an den Wert von "i" gebunden ist und somit jedes "li" einen separaten Indexparameter für sich selbst erhält. Aber ist die "let" -Anweisung in meinem Code nicht dasselbe? Ich habe auch versucht, die if (intervalTimerId) {clearInterval();} in meinen Code zu ändern, aber es funktioniert immer noch nicht. Kannst du bitte etwas erklären? – SamC

0

Dies ist, was Sie wahrscheinlich auf der Suche nach:

// 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>

Verwandte Themen