Guilhem Guilhem - 7 months ago 57
Javascript Question

lightweight metronome does not work?

i'm trying to make here a simple visual metronome with only javascript and Jquery.
it does not seem to work well and i can't figure out why.

Do you ?



function metronome() {


var slidevalue = document.getElementById('speed').value;
var delay = 1000 / ((slidevalue * 9) / 60);
var timer= setInterval(function(){


setTimeout(function(){ $("#metronome").css({"background-color":"red"});},delay);
setTimeout(function(){ $("#metronome").css({"background-color":"green"});},2*delay);

}, 2*delay);
}

.round {

border-radius: 50%;
width: 20px;
height: 20px;
margin: 0 auto;
border: solid 2px #59B3AD;
border-color:#59B3AD;

}
.center {
margin:0 auto;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="range" id="speed" min="1" max="20" step="2" onchange="metronome()" class="center">
<div id="metronome" class="round"></div>




Answer

When the slider changes, you need to clear your previous interval before you set a new one. It's also redundant to use both setInterval and setTimeout for this task - setInterval by itself will do.

Here is a working example:

var prev_interval;
var tick_flip;

function metronome() {
  var slidevalue = document.getElementById('speed').value;
  var delay = 1000 / ((slidevalue * 9) / 60);
  clearInterval(prev_interval);
  prev_interval = setInterval(function() {
    if (tick_flip) {
      $("#metronome").css({
        "background-color": "red"
      });
      tick_flip = false;
    } else {
      $("#metronome").css({
        "background-color": "green"
      });
      tick_flip = true;
    }
  }, delay);
}

metronome();
.round {
  border-radius: 50%;
  width: 20px;
  height: 20px;
  margin: 0 auto;
  border: solid 2px #59B3AD;
  border-color: #59B3AD;
}
.center {
  margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="range" id="speed" min="1" max="20" step="2" onchange="metronome()" class="center">
<div id="metronome" class="round"></div>

Comments