How can I make setInterval also work when a tab is inactive in Chrome?

后端 未结 13 1968
被撕碎了的回忆
被撕碎了的回忆 2020-11-21 09:59

I have a setInterval running a piece of code 30 times a second. This works great, however when I select another tab (so that the tab with my code becomes inacti

13条回答
  •  死守一世寂寞
    2020-11-21 10:37

    I ran into the same problem with audio fading and HTML5 player. It got stuck when tab became inactive. So I found out a WebWorker is allowed to use intervals/timeouts without limitation. I use it to post "ticks" to the main javascript.

    WebWorkers Code:

    var fading = false;
    var interval;
    self.addEventListener('message', function(e){
        switch (e.data) {
            case 'start':
                if (!fading){
                    fading = true;
                    interval = setInterval(function(){
                        self.postMessage('tick');
                    }, 50);
                }
                break;
            case 'stop':
                clearInterval(interval);
                fading = false;
                break;
        };
    }, false);
    

    Main Javascript:

    var player = new Audio();
    player.fader = new Worker('js/fader.js');
    player.faderPosition = 0.0;
    player.faderTargetVolume = 1.0;
    player.faderCallback = function(){};
    player.fadeTo = function(volume, func){
        console.log('fadeTo called');
        if (func) this.faderCallback = func;
        this.faderTargetVolume = volume;
        this.fader.postMessage('start');
    }
    player.fader.addEventListener('message', function(e){
        console.log('fader tick');
        if (player.faderTargetVolume > player.volume){
            player.faderPosition -= 0.02;
        } else {
            player.faderPosition += 0.02;
        }
        var newVolume = Math.pow(player.faderPosition - 1, 2);
        if (newVolume > 0.999){
            player.volume = newVolume = 1.0;
            player.fader.postMessage('stop');
            player.faderCallback();
        } else if (newVolume < 0.001) {
            player.volume = newVolume = 0.0;
            player.fader.postMessage('stop');
            player.faderCallback();
        } else {
            player.volume = newVolume;
        }
    });
    

提交回复
热议问题