setInterval делает паузу в Android Browser / Mobile Safari, когда время ожидания экрана - PullRequest
2 голосов
/ 27 мая 2010

Я построил простой таймер на основе JavaScript для мобильного веб-приложения; для примера:

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

Это прекрасно работает как в браузере Mobile Safari, так и в браузере Android. Он будет регистрировать консоль каждую секунду и увеличивать значение соответственно. (Хорошо, браузер Android не поддерживает console.log, но давайте предположим, что он есть.)

Проблема: если время ожидания экрана (т.е. пользователь перестал взаимодействовать со страницей), функция setInterval приостанавливается. Он возобновляется, когда пользователь снова включает свой экран. Это не сработает для меня, так как мне нужен таймер, чтобы продолжать работать.

Вопросы: Есть ли способ предотвратить приостановку функции setInterval по истечении времени ожидания экрана? Если нет, можно ли предотвратить тайм-аут экрана? Любые другие альтернативы?

Заранее спасибо!

Ответы [ 2 ]

5 голосов
/ 27 мая 2010

В основном нет. Телефон переходит в спящий режим для экономии заряда батареи, когда время ожидания экрана истекло. Так как вы ничего не видите, большое количество задач обработки остановлено. Подобные вещи будут происходить при смене вкладок / окон (страница выгружается из памяти). В настоящее время нет способа запросить, чтобы устройство оставалось включенным из веб-приложения. В будущем поддержка Android для доступа к оборудованию может обеспечить эту функциональность, но лично я сомневаюсь в этом.

Если вам нужна постоянная поддержка, вам нужно написать собственные приложения для обеих систем (плюс на Android он всегда может работать).

0 голосов
/ 22 июня 2017

Вы можете использовать API видимости страницы, чтобы определить, когда страница скрыта или видна. Например, если пользователь отходит от браузера и возвращается обратно или экран выключается и включается.

Я использовал этот ответ , чтобы помочь создать решение. Вам нужно будет сохранить время, которое вы установили ваш интервал. Затем, когда прослушиватель события 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...