2017-09-12 27 views
1

私は簡単な「Simon Game」を作ろうとしています。私は現在、1秒間divに 'on'クラスを追加しようとしています。そして、同じ時間量でそのクラスを削除します。クラスを追加するsetInterval()と同じ時間にクラスを削除する

私は4つのdivを持っており、数字のシーケンスに応じて点滅しています。 [0, 1, 2, 3]。これにより、1秒間はdiv[0]が点滅し、1秒間はオフになり、div[1]に移動したり消したりするなどの処理が行われます。ここで

は私の関数は

/** 
* sequence => array [0, 1, 2, 3] 
* speed => int 1000 (one second) 
*/ 
playSequence: function(sequence, speed){ 
    var self = this; 

    // removes class 'on' 
    view.turnOffPads(); 
    setTimeout(function(){ 
     // adds the 'on' class to a specific div 
     view.lightUpPad(model.startupSequence[model.count]); 
    }, speed/2); 

    setTimeout(function(){ 
     model.count++; // keeps track of the iterations 
     if (model.count < sequence.length) { // if we are still iterating 
      self.playSequence(sequence, speed); // light up the next div 
     } else { 
      model.count = 0; // set back to zero 
     } 
    }, speed); 
}, 

でこれに伴う問題は、私は互いに2つのsetTimeout関数を使用していますし、それが動作しますが、より良い方法があるかどうか、私は疑問に思っていることです。あなたが見ている場合は、私のモデルオブジェクト内のカウント変数を使用して繰り返しを追跡しています。ここで

は私の完全なjavascriptのアプリは、これまで...

$(function(){ 

    var model = { 
     on: false, 
     strictMode: false, 
     startupSequence: [0, 1, 2, 3, 3, 3, 2, 1, 0, 3, 2, 1, 0, 2, 1, 3], 
     score: 0, 
     sequence: [], 
     count: 0, 
    } 

    var controller = { 
     init: function(){ 
      view.cacheDOM(); 
      view.bindEvents(); 
     }, 
     getSequence: function(){ 
      // get a random number from one to 4 
      var random = Math.floor(Math.random() * 4); 
      // push it to the sequence array 
      model.sequence.push(random); 
      console.log(model.sequence); 
      // play it 
      this.playSequence(model.sequence); 
     }, 

     /** 
     * sequence => array [0, 1, 2, 3] 
     * speed => int 1000 (one second) 
     */ 
     playSequence: function(sequence, speed){ 
      console.log(sequence.length); 
      var self = this; 

      view.turnOffPads(); 
      setTimeout(function(){ 
       view.lightUpPad(model.startupSequence[model.count]); 
      }, speed/2); 

      setTimeout(function(){ 
       model.count++; 
       if (model.count < sequence.length) { 
        self.playSequence(sequence, speed); 
       } else { 
        model.count = 0; 
       } 
      }, speed); 
      // view.turnOffPads(); 
     }, 
    } 

    var view = { 
     cacheDOM: function(){ 
      this.$round = $('#round'); 
      this.$start = $('#start'); 
      this.$strict = $('#strict'); 
      this.$pad = $('.pad'); 

      this.$padArray = document.getElementsByClassName('pad'); 
     }, 
     bindEvents: function(){ 
      this.$start .change(this.start.bind(this)); 
      this.$strict.change(this.setStrictMode.bind(this)); 
     }, 
     start: function(){ 
      // turn on pads 
      if (model.on) { 
       this.$pad.removeClass('on'); 
       this.$round.text('--'); 
       model.on = false; 
       // reset everything 
      } else { 
       this.$round.text(model.score); 
       model.on = true; 
       controller.playSequence(model.startupSequence, 100) 
       // controller.getSequence(); 
      } 
     }, 
     lightUpPad: function(i){ 
      $(this.$padArray[i]).addClass('on'); 
     }, 
     turnOffPads: function(){ 
      this.$pad.removeClass('on'); 
     }, 
     setStrictMode: function(){ 
      if (model.strictMode) { 
       model.strictMode = false; 
      } else { 
       model.strictMode = true; 
      } 
     } 
    } 

    controller.init(); 
}); 

は、クラスを追加し、クラスを削除するクリーンな方法はありますか?

答えて

1

私はあなたが一連のコマンドにボタンのリストを回すことができると思います。コマンドがなくなるまでコマンドを再生するには、単一のsetIntervalを使用します。 setIntervalは、オンとオフをちょうど同じ長さにしたい場合は1秒間隔を使用することができますが、異なる時間を簡単に許可するには少し速く設定することもできます。

以下の例は実際にコードに基づいているのではなく、そのアイデアを説明するためのものです。ボタンの配列を押した状態で(コードのボタンで)開始します。それらはgetSequenceに渡されます。これは一連のコマンドを返します。この場合、ボタンをオンにするだけで、シーケンスは赤、赤、赤、赤、 ''、 ''、 ''、 '' 4 'インターバルの間、それからそれを4'インターバルのためにオフにします。こうすることで、複雑なシーケンスを作成することができ、マイナーな調整で複数のボタンを同時に点灯させることもできます。

この例の間隔は1/10秒に設定されています。各色は10ステップ(= 1秒)で再生され、各ポーズは5ステップ(= 0.5秒)で再生されます。コンソールには、演奏するボタン/色の基本配列と、より精巧な演奏シーケンスが表示されます。

// The play function plays a sequence of commands 
 
function play(sequence) { 
 
    var index = 0; 
 
    var lastid = ''; 
 
    var timer = setInterval(function(){ 
 
    // End the timer when at the end of the array 
 
    if (++index >= sequence.length) { 
 
     clearInterval(timer); 
 
     return; 
 
    } 
 
    var newid = sequence[index]; 
 
     
 
    if (lastid != newid) { 
 
     // Something has changed. Check and act. 
 
    
 
     if (lastid != '') { 
 
     // The last id was set, so lets switch that off first. 
 
     document.getElementById(lastid).classList.remove('on'); 
 
     console.log('--- ' + lastid + ' off'); 
 
     } 
 
     
 
     if (newid != '') { 
 
     // New id is set, switch it on 
 
     document.getElementById(newid).classList.add('on'); 
 
     console.log('+++ ' + newid + ' on'); 
 
     } 
 
     lastid = newid; 
 
    } 
 
    }, 100); 
 
} 
 

 
// generateSequence takes a list of buttons and converts them to a 
 
// sequence of color/off commands. 
 
function generateSequence(buttons) { 
 
    var result = []; 
 
    for (var b = 0; b < buttons.length; b++) { 
 
    // 'On' for 10 counts 
 
    for (var i = 0; i < 10; i++) { 
 
     result.push(buttons[b]); 
 
    } 
 
    if (b+1 < buttons.length) { 
 
     // 'Off' for 5 counts 
 
     for (var i = 0; i < 5; i++) { 
 
     result.push(''); 
 
     } 
 
    } 
 
    } 
 
    // One 'off' at the end 
 
    result.push(''); 
 
    
 
    return result; 
 
} 
 

 
var buttons = ['red', 'green', 'red', 'yellow', 'yellow', 'blue']; 
 
console.log(buttons); 
 
var sequence = generateSequence(buttons); 
 
console.log(sequence); 
 
play(sequence);
div.button { 
 
    width: 100px; 
 
    height: 100px; 
 
    opacity: .5; 
 
    display: inline-block; 
 
} 
 
div.button.on { 
 
    opacity: 1; 
 
} 
 
#red { 
 
    background-color: red; 
 
} 
 
#green { 
 
    background-color: green; 
 
} 
 
#yellow { 
 
    background-color: yellow; 
 
} 
 
#blue { 
 
    background-color: blue; 
 
}
<div id="red" class="button"></div> 
 
<div id="green" class="button"></div> 
 
<div id="yellow" class="button"></div> 
 
<div id="blue" class="button"></div>

1

TLDR;)

あなたがする必要があるのはsetInterval()またはsetTimeout()を使用して、コールバック関数内の要素からクラスを追加または削除するelement.classList.toggle()を使用することです。

点滅を止めたい場合は、clearTimeout()またはclearInterval()を使用してください。ここで

は例です:

var d = document.getElementById("test"); 
 
var b = document.querySelector("button"); 
 

 
b.addEventListener("click", function(){ 
 
    // Cancel the timer 
 
    clearTimeout(timer); 
 
}); 
 

 
// Assign the timer's ID to a variable so that 
 
// you can stop it later 
 
var timer = setInterval(function(){ 
 
    // Toggle the use of the lightUp class 
 
    test.classList.toggle("lightUp"); 
 
},1000);
#test { 
 
    width:100px; 
 
    height:100px; 
 
    background-color:blue; /* <-- blue will be the default color */ 
 
} 
 

 
#test.lightUp { 
 
    background-color:yellow; 
 
}
<div id="test"></div> 
 
<button>Stop Blinking</button>

1

使用のsetInterval代わりIは4 divisonを作成し、1秒間の各部門を点滅しているのsetTimeoutの。

var i = 0, 
 
    j = 4; 
 

 
function blink(i) { 
 
    new Promise(function(resolve, reject) { 
 
    x = setTimeout(function() { 
 
    document.querySelectorAll(".post-text")[i].classList.add("myClass"); 
 
    resolve("added"); 
 
    }, 1000) 
 
    }).then(function(a) { 
 
    new Promise(function(res, rej) { 
 
    setTimeout(function() { 
 
     clearInterval(x); 
 
     document.querySelectorAll(".post-text")[i].classList.remove("myClass"); 
 
     res("deleted"); 
 
    }, 1000) 
 
    }).then(function(a) { 
 
    i++; 
 
    if (i < j) { 
 
     blink(i); 
 
    } else { 
 
     i = 0; 
 
     blink(i); 
 
    } 
 
    }); 
 

 
    }); 
 
} 
 
blink(i);
.myClass { 
 
    background-color:yellow; 
 
}
<div class="post-text">A</div> 
 
<div class="post-text">B</div> 
 
<div class="post-text">C</div> 
 
<div class="post-text">D</div>

関連する問題