当屏幕超时时,setInterval在Android Browser / Mobile Safari中暂停

时间:2010-05-27 04:51:12

标签: javascript mobile-safari mobile-website setinterval android-browser

我为移动网络应用程序构建了一个简单的基于JavaScript的计时器;为了举例:

var a = 0;
setInterval(function() {
    console.log('a', a);
    a++;
}, 1000);

这在Mobile Safari和Android Browser中运行良好。它将每秒登录到控制台并相应地增加a的值。 (好吧,Android浏览器没有console.log支持,但让我们假设它。)

问题:如果屏幕超时(即用户停止与页面交互),则setInterval函数暂停。当用户再次打开屏幕时,它会恢复。这对我来说不起作用,因为我需要计时器才能继续运行。

问题:有没有办法阻止setInterval函数在屏幕超时时暂停?如果没有,是否可以防止屏幕超时?还有其他选择吗?

提前致谢!

2 个答案:

答案 0 :(得分:5)

基本上没有。当屏幕超时时,手机进入睡眠状态以节省电池电量。由于无论如何都看不到任何东西,因此停止了大量的处理任务。更改选项卡/窗口时会发生类似的事情(页面从内存中卸载)。现在无法请求设备从Web应用程序保持打开状态。 Android中用于访问硬件的未来支持可能会提供此功能,但我个人对此表示怀疑。

如果您需要始终运行支持,则需要为两个系统编写本机应用程序(在Android上它总能运行)。

答案 1 :(得分:0)

您可以使用Page Visibility API来检测页面何时隐藏或可见。例如,如果用户离开浏览器并再次返回或屏幕关闭然后再打开。

我使用此answer来帮助创建解决方案。 您需要存储设置间隔的时间。然后,当visibilityChange事件侦听器指示文档再次可见时,您可以计算自首次启动间隔以来所经过的时间量,并根据需要更新数据。

在我的情况下,我在Angular2项目中创建了倒计时器。我的页面在iPad上运行,只要屏幕关闭,计时器就会暂停。所以我在ngOnInit()中添加了事件监听器。然后当屏幕重新打开时,我可以更新我的计时器,以显示自启动以来剩下的正确时间。

我正在使用npm包来处理我的约会时间。 timerInfo对象是一个类变量,它由间隔回调更新。 self.zone.run()用于将更改传播到DOM,以便显示更新的时间。

写在打字稿中:

private timerInfo:{
    days?:number,
    hours?:number,
    minutes:number,
    seconds:number
};
private startTime:Moment = moment();
private timerDuration:number = 20;  // in minutes
private timerHandle:any;

ngOnInit() {
    this.setVisibilityListener();
}

private setVisibilityListener():void {
    var self = this;
    var hidden, visibilityState, visibilityChange;

    if (typeof document.hidden !== "undefined") {
        hidden = "hidden";
        visibilityChange = "visibilitychange";
        visibilityState = "visibilityState";
    }

    var document_hidden = document[hidden];

    document.addEventListener(visibilityChange, function () {
        if (document_hidden != document[hidden]) {
            if (document[hidden]) {
                // Document hidden
                console.log("document hidden");
            } else {
                // Document shown
                console.log("document shown; setCountDownTimer()");
                self.setCountDownTimer();
            }

            document_hidden = document[hidden];
        }
    });
}

private setCountDownTimer():void {
    var self = this;
    if (self.startTime) {
        var startMoment = moment(self.startTime);
        var endMoment = startMoment.add(self.timerDuration, "minutes");
        console.log("endMoment: ", endMoment.toISOString());

        self.clearTimer();

        var eventTime = endMoment.unix();
        var currentTime = moment().unix();
        var diffTime = eventTime - currentTime;
        var duration = moment.duration(diffTime * 1000, 'milliseconds');
        var interval = 1000;

        // if time to countdown
        if (diffTime > 0) {
            self.timerHandle = setInterval(() => {
                self.zone.run(() => {
                    var diff = duration.asMilliseconds() - interval;
                    if (diff < 0) {
                        self.clearTimer();
                        self.timerComplete();
                    } else {
                        duration = moment.duration(duration.asMilliseconds() - interval, 'milliseconds');

                        self.timerInfo = {
                            days: moment.duration(duration).days(),
                            hours: moment.duration(duration).hours(),
                            minutes: moment.duration(duration).minutes(),
                            seconds: moment.duration(duration).seconds()
                        };
                        // console.log("timerInfo: ", JSON.stringify(self.timerInfo));
                    }
                });
            }, 1000);
        } else {
            self.timerComplete();
        }
    }
}

private clearTimer():void {
    if (this.timerHandle) {
        clearInterval(this.timerHandle);
        this.timerHandle = null;
    }
}
相关问题