I'm having problems getting standard javascript timers to clear on mobile devices (Android and iOS, phone and tablet).
My page contains 2 buttons, a play/pause toggle and a stop button (both FontAwesome icons), the simple HTML for which is:
<span class="fa fa-pause control-button" id="pause-button"></span>
<span class="fa fa-stop control-button" id="stop-button"></span>
The interval is initiated with the following function:
var interval = function() {
$('.control-button').fadeIn(300);
//initiate the interval
infiniteInterval = window.setInterval(Tiles.infiniteTick, speed);
};
Where speed is defined in an earlier function (default is 300). infiniteTick is a very simple function which is working fine. I haven't explained it here as it would require an explanation of the whole program but I can provide code if required.
The play and pause toggles are as follows:
$('body').on('click touchstart', '#pause-button', function() {
if ($(this).hasClass('fa-pause')) {
window.clearInterval(infiniteInterval);
$(this).removeClass('fa-pause');
$(this).addClass('fa-play');
} else {
infiniteInterval = window.setInterval(Tiles.infiniteTick, speed);
$(this).removeClass('fa-play');
$(this).addClass('fa-pause');
}
});
Finally, the interval is terminated with this (some purely aesthetic extras removed for simplicity)
$('body').on('click touchstart', '#stop-button', function() {
window.clearInterval(infiniteInterval);
$('.control-button').fadeOut(300);
});
I initially thought from researching this that it was due to click events not being properly registered, but as you can see I have added touchstart
to all the click events and that has made no difference. It's working absolutely fine on all desktop browsers.
Any help is greatly appreciated, and I'd be happy to answer any further questions.
Thanks,
Ben
I'm having problems getting standard javascript timers to clear on mobile devices (Android and iOS, phone and tablet).
My page contains 2 buttons, a play/pause toggle and a stop button (both FontAwesome icons), the simple HTML for which is:
<span class="fa fa-pause control-button" id="pause-button"></span>
<span class="fa fa-stop control-button" id="stop-button"></span>
The interval is initiated with the following function:
var interval = function() {
$('.control-button').fadeIn(300);
//initiate the interval
infiniteInterval = window.setInterval(Tiles.infiniteTick, speed);
};
Where speed is defined in an earlier function (default is 300). infiniteTick is a very simple function which is working fine. I haven't explained it here as it would require an explanation of the whole program but I can provide code if required.
The play and pause toggles are as follows:
$('body').on('click touchstart', '#pause-button', function() {
if ($(this).hasClass('fa-pause')) {
window.clearInterval(infiniteInterval);
$(this).removeClass('fa-pause');
$(this).addClass('fa-play');
} else {
infiniteInterval = window.setInterval(Tiles.infiniteTick, speed);
$(this).removeClass('fa-play');
$(this).addClass('fa-pause');
}
});
Finally, the interval is terminated with this (some purely aesthetic extras removed for simplicity)
$('body').on('click touchstart', '#stop-button', function() {
window.clearInterval(infiniteInterval);
$('.control-button').fadeOut(300);
});
I initially thought from researching this that it was due to click events not being properly registered, but as you can see I have added touchstart
to all the click events and that has made no difference. It's working absolutely fine on all desktop browsers.
Any help is greatly appreciated, and I'd be happy to answer any further questions.
Thanks,
Ben
- 1 I believe you have 2 handlers for same button. I'm not sure if it would work but if a class is the only way you want to decide, try` $(element).hasClass()`. – Rajesh Commented Nov 11, 2015 at 3:27
- Thought it would be worth mentioning that on all devices, the other code in the functions does execute fine. – Ben Kolya Mansley Commented Nov 11, 2015 at 3:33
- if you have access to a mac, you might try installing apple's developer tools, from there you can use the iPhone/iPad simulator in tandem with safari to debug javascript issues on mobile devices. try this: webdesign.tutsplus./articles/… – acolchagoff Commented Nov 11, 2015 at 4:00
-
Where in your code are you declaring
infiniteInterval
? – Femi Commented Nov 11, 2015 at 4:09 -
at the start of the module that these functions are contained in,
var infiniteInterval = null;
– Ben Kolya Mansley Commented Nov 11, 2015 at 4:11
2 Answers
Reset to default 5I've managed to fix the problem, which it turns out was twofold.
Firstly, the click event was firing twice. This was fixed using this SO question: jquery mobile click event fires twice
Secondly, I wasn't properly clearing the intervals.
Edited with @MjrKusanagi's ments
A simple call to clearInterval()
before every setInterval()
call has fixed the problem, making sure that the interval was always reset before starting again.
Original sketchy workaround:
I've called
infiniteInterval = null;
after every clearInterval()
call, as well as wrapping the setInterval()
calls with
if (infiniteInterval === null)
Thanks to everyone who mented and hopefully this will help someone sometime :)
First, your click event is firing twice because of this sentence:
$('body').on('click touchstart', '#pause-button', function() { ...
It listens to two events click
and touchstart
, thus it will be triggered twice, once on click
event and once on touchstart
event. This is also why your code works well on pc because there's no touchstart
event in pc browsers.
So every time you touch that button, things happened like this:
1st event triggered
interval set, handle id is 1 (for example)
infiniteInterval = 1
2nd event triggered
another interval set, handle id is 2
infiniteInterval = 2
And now there's two timing cycles running instead of one, and you only have track of the second one. When you invoke clearInterval
, only the handle id = 2
interval is cleared, and 1
is still running.
So the solution is:
Fix the twice-triggered events problem, by only listen to
click
. (tryfastclick
orzepto
or other lib to deal with the click latency on mobile devices)As your own answer said, set
infiniteInterval
tonull
, and if it is notnull
do not ever start another interval. (I think it is more elegant than "always clear before setting" works, asinfiniteInterval
works as a flag of running interval)
Hope these could solve your problem.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745653757a4638419.html
评论列表(0条)