【发布时间】:2021-08-05 09:28:06
【问题描述】:
我正在使用 Javascript setInterval 和 web worker 实现倒数计时器。它在桌面上运行良好,但在移动浏览器中,当浏览器最小化(非活动模式)时,计时器会变慢。
有没有办法防止移动设备中的 setInerval 减速问题?
这是我的代码的一瞥:
script.js
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
document.addEventListener(visibilityChange, function (event) {
if( document[hidden] === false ){
// distance is a value of difference between current time and the end time
var days = Math.floor(distance / (60 * 60 * 24));
var hours = Math.floor((distance % (60 * 60 * 24)) / (60 * 60));
var minutes = Math.floor((distance % (60 * 60)) / 60);
var seconds = Math.floor(distance % 60);
var secondsLeft = (days * 24 * 3600) + (hours * 3600) + (minutes * 60) + seconds;
startTimer(distance, secondsLeft);
}
});
function startTimer(distance, secondsLeft)
{
// First check whether Web Workers are supported
if (typeof(Worker)!=="undefined"){
// Check whether Web Worker has been created. If not, create a new Web Worker based on the Javascript file simple-timer.js
if(w == null){
w = new Worker("../js/timer-worker.js");
w.postMessage({
'distance': distance,
'secondsLeft': secondsLeft
});
}
// Update timer div with output from Web Worker
w.onmessage = function (event) {
console.log(event.data.time_left_str);
};
} else {
// Web workers are not supported by your browser
console.log('Sorry, your browser does not support Web Workers ...');
}
}
timer-worker.js
var timerStart = true;
function myTimer(distance)
{
function pad(n) {
return (n < 10 ? "0" + n : n);
}
var hours = Math.floor((distance % (60 * 60 * 24)) / (60 * 60));
var minutes = Math.floor((distance % (60 * 60)) / 60);
var seconds = Math.floor(distance % (60));
var total_seconds = (hours * 60 * 60) + (minutes * 60) + seconds;
if( hours > 0 ){
time_left_str = pad(hours) + " hrs " + pad(minutes) + " mins " + pad(seconds) + " secs ";
}
else if( minutes > 0 ){
time_left_str = pad(minutes) + " mins " + pad(seconds) + " secs ";
}
else{
time_left_str = pad(seconds) + " secs ";
}
// return output to Web Worker
postMessage({
'time_left_str': time_left_str,
'total_seconds': total_seconds,
'distance_changed': distance
});
}
if (timerStart){
distance = null;
secondsLeft = null;
self.addEventListener('message', function(event) {
if(typeof(event.data.distance)!=="undefined"){
distance = event.data.distance;
}
if(typeof(event.data.secondsLeft)!=="undefined"){
secondsLeft = event.data.secondsLeft;
}
}, false);
// get current time
var d0=(new Date()).valueOf();
// repeat myTimer(d0) every 100 ms
myVar = setInterval(function(e){
//console.log('distance :: ' + distance);
myTimer(distance, secondsLeft);
distance--;
}, 1000);
// timer should not start anymore since it has been started
timerStart = false;
}
【问题讨论】:
-
setInterval和setTimeout都不保证准时到达,请参阅 this section on MDN 了解更多详情。没有办法避免这种情况,因为这不是缺陷,而是用户方面的好处:随机网站不能随意占用浏览器。 -
我的要求是确保计时器运行,而不管浏览器在移动设备中是否处于非活动状态。正如我所说,它在我在桌面测试的所有浏览器中都能完美运行。只有移动浏览器存在问题。到底有没有出来?
标签: javascript setinterval web-worker countdowntimer