0

Desired Behaviour

Create two "spinners" for hour and minute definition using requestAnimationFrame().

Current Behaviour

I've adapted this solution to incorporate two "spinner" instances.

The hours spinner is working, however clicking on the arrow buttons to in/decrement the minutes value is changing the hours value, instead of the minutes value.

What I've Tried

What I've tried feels a bit repetitive, as I've tried to call requestAnimationFrame() twice, but I can't think of a more dynamic way to execute it.

jsFiddle

jsFiddle link

//adapted from:
//https://stackoverflow.com/a/28127763

// the hrs 'input' area
var $hrs_input=$('.hrs_input > span');

// the mins 'input' area
var $mins_input=$('.mins_input > span');

// common variables
// the starting hr and mins value
var number=0;
// isDown starting value
var isDown=0;
// delay in changing value
var delay=200;
// ??
var nextTime=0;

requestAnimationFrame(watcher);
requestAnimationFrame(watcher2); // eek?

// ======= BEGIN for hours handling

$(".hr_arrow").mousedown(function(e){handleMouseDown(e);});
$(".hr_arrow").mouseup(function(e){handleMouseUp(e);});
$(".hr_arrow").mouseout(function(e){handleMouseUp(e);});

function handleMouseDown(e){
e.preventDefault();
e.stopPropagation();
if (e.target.id=='add_hr') {
isDown=1;
}
else if (e.target.id!='add_hr')  {
isDown=-1;
}
}

function handleMouseUp(e){
e.preventDefault();
e.stopPropagation();
isDown=0;
}

function watcher(time) {

requestAnimationFrame(watcher);

if (time < nextTime) { 
return;
}

nextTime = time + delay;

// when adding
if (isDown === 1) {
// no conditional needed
number+=isDown;
$hrs_input.text(number);
}
// when subtracting
else if (isDown === -1) {
// conditional needed - only subtract if number is not 0
if (number !=0) {
number+=isDown;
$hrs_input.text(number);
}
}
}

// ======= END for hours handling


// ======= BEGIN for mins handling 
// just repeats the above hrs handling, with different 
// function names and div references

$(".min_arrow").mousedown(function(e){handleMouseDown2(e);});
$(".min_arrow").mouseup(function(e){handleMouseUp2(e);});
$(".min_arrow").mouseout(function(e){handleMouseUp2(e);});

function handleMouseDown2(e){
e.preventDefault();
e.stopPropagation();
if (e.target.id=='add_min') {
isDown=1;
}
else if (e.target.id!='add_min')  {
isDown=-1;
}
}

function handleMouseUp2(e){
e.preventDefault();
e.stopPropagation();
isDown=0;
}

function watcher2(time) {

requestAnimationFrame(watcher2);

if (time < nextTime) { 
return;
}

nextTime = time + delay;

// when adding
if (isDown === 1) {
// no conditional needed
number+=isDown;
$mins_input.text(number);
}
// when subtracting
else if (isDown === -1) {
// conditional needed - only subtract if number is not 0
if (number !=0) {
number+=isDown;
$mins_input.text(number);
}
}
}

// ======= END for mins handling 
.hrs_input, .mins_input {
  background: #9be672 none repeat scroll 0 0;
  border-radius: 2px;
  color: #333;
  display: inline-block;
  font-family: arial;
  font-size: 13px;
  margin: 0 0 0 2px;
  min-width: 62px;
  padding: 0 5px;
}

.hr_arrow, .min_arrow {
  background: #ccc none repeat scroll 0 0;
  border: 1px solid #999;
  font-family: arial;
  font-size: 12px;
}

.hr_arrow:hover, .min_arrow:hover {
  cursor:pointer;
}

p {
  font-family:arial;
  font-size:14px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<p>Click the up and down arrows to in/decrease the hours.</p>
<p>Desired Behaviour:  For minutes in/decrementing to work the same way.</p>
<!-- BEGIN hrs -->
<span class="hrs_input">hrs:  <span>&nbsp;</span>
</span>
<span id="add_hr" class="hr_arrow">&#x25B2;</span>
<span class="hr_arrow">&#x25BC;</span>
<!-- END hrs -->
<!-- BEGIN mins -->
<span class="mins_input">mins:  <span>&nbsp;</span>
</span>
<span id="add_min" class="min_arrow">&#x25B2;</span>
<span class="min_arrow">&#x25BC;</span>
<!-- END mins -->

Code

It's a fairly bulky chunk of code, but I'm thinking the problem may arise from calling requestAnimationFrame() twice, ie:

requestAnimationFrame(watcher);
requestAnimationFrame(watcher2);
Community
  • 1
  • 1
user1063287
  • 10,265
  • 25
  • 122
  • 218

1 Answers1

0

You never pass the if (time < nextTime) in the second watcher, because the first watcher always increases the nextTime value before.

This happens because both watchers share the same global time and nextTime variables (this probably applies to number and isDown too).

Check out this fiddle: https://jsfiddle.net/kky0bdkx/

It has different global variables for each watcher, in order to avoid conflicts. This is one of the issues when working with globals. A better solution will probably be to figure out a way of rewriting the watchers with scoped variables.

Gilad Artzi
  • 3,034
  • 1
  • 15
  • 23