Is there a way to detect if a browser window is not currently active?

前端 未结 19 2114
无人共我
无人共我 2020-11-21 04:40

I have JavaScript that is doing activity periodically. When the user is not looking at the site (i.e., the window or tab does not have focus), it\'d be nice to not run.

19条回答
  •  谎友^
    谎友^ (楼主)
    2020-11-21 04:44

    I started off using the community wiki answer, but realised that it wasn't detecting alt-tab events in Chrome. This is because it uses the first available event source, and in this case it's the page visibility API, which in Chrome seems to not track alt-tabbing.

    I decided to modify the script a bit to keep track of all possible events for page focus changes. Here's a function you can drop in:

    function onVisibilityChange(callback) {
        var visible = true;
    
        if (!callback) {
            throw new Error('no callback given');
        }
    
        function focused() {
            if (!visible) {
                callback(visible = true);
            }
        }
    
        function unfocused() {
            if (visible) {
                callback(visible = false);
            }
        }
    
        // Standards:
        if ('hidden' in document) {
            document.addEventListener('visibilitychange',
                function() {(document.hidden ? unfocused : focused)()});
        }
        if ('mozHidden' in document) {
            document.addEventListener('mozvisibilitychange',
                function() {(document.mozHidden ? unfocused : focused)()});
        }
        if ('webkitHidden' in document) {
            document.addEventListener('webkitvisibilitychange',
                function() {(document.webkitHidden ? unfocused : focused)()});
        }
        if ('msHidden' in document) {
            document.addEventListener('msvisibilitychange',
                function() {(document.msHidden ? unfocused : focused)()});
        }
        // IE 9 and lower:
        if ('onfocusin' in document) {
            document.onfocusin = focused;
            document.onfocusout = unfocused;
        }
        // All others:
        window.onpageshow = window.onfocus = focused;
        window.onpagehide = window.onblur = unfocused;
    };
    

    Use it like this:

    onVisibilityChange(function(visible) {
        console.log('the page is now', visible ? 'focused' : 'unfocused');
    });
    

    This version listens for all the different visibility events and fires a callback if any of them causes a change. The focused and unfocused handlers make sure that the callback isn't called multiple times if multiple APIs catch the same visibility change.

提交回复
热议问题