简体   繁体   中英

How to create hours and minutes spinner using requestAnimationFrame()?

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM