2017-05-13 4 views
0

このコードでどこが間違っているのかわかりません。私が探しています何Clickイベントハンドラ内の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(); 
     }); 
    } 

私のロジックは次のとおりです。

ザ・ループのために李さんのそれぞれの上にクリック条件を設定します。ここでクリックされるとsetInterval関数が呼び出され、もう一度クリックするとその関数が停止します。

どこが間違っていますか?ありがとう。

+0

イベントリスナー内で同じ変数名を割り当てると、 'writeMe'は関数ではありません。タイマーIDです。それが機能ではないことをあなたに伝えるブラウザコンソールのエラーを表示する必要があります – charlietfl

+0

ありがとう。変数名writeMeをtellMeに変更しました。ここには[JSBin](http://jsbin.com/jibitil)があります。私が今直面している2つの問題は、 'clearInterval()not working'です。タブをクリックし続けるうちに、' animation is speeding'! – SamC

+0

@SamC、チェック[私の答え](http://stackoverflow.com/a/43953682/2545680) –

答えて

0

あなたのアプローチにはいくつかの問題があります。

はあなたが元の質問では
  • writeMeという名前の関数が、私が上書きしていたn範囲を設定すると、範囲がvar writeMe = setInterval(writeMe, 1000);になります。しかし、あなたはまた、あなたがその名前をtellMeに変更したことをコメントで述べましたが、それはその矛盾を解決したはずです。あなたのJSBin
    • あなたは値としてループiのインデックスを使用しようとしています。可変スコープとクロージャを理解する必要があります。クリックは、ループが終了してから長く続き、クリックする要素に関係なく、iの値は常に5(この場合)にとどまる場合があります。
    • writeMe2, writeMe3...のような複数のwriteMeメソッドの宣言は解決策ではありません。おそらく1つまたは2つの値の変更を除いて、他と同じことをする別のwriteMeメソッドを追加する必要があります。
    • varでローカル変数として宣言することなく、ループ内で複数回iを使用します。上部スコープ変数をクロージャスコープにシャドーイングしています。あなたのユースケース(まだ)には影響しませんが、将来の問題にコードを公開しています。

次のスニペットを使用してみてください。

(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を忘れていないことです。したがって、以前のタブで最初にclearIntervalを使用し、次のタブをクリックしない限り、前のクリックの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>

関連する問題