it-swarm.it

Rileva se la scheda Browser ha lo stato attivo

Esiste un modo affidabile tra browser per rilevare l'attivazione di una scheda.

Lo scenario è che abbiamo un'applicazione che esegue regolarmente il polling per i prezzi delle azioni, e se la pagina non ha il focus potremmo fermare il polling e salvare tutti il ​​rumore del traffico, specialmente perché le persone sono fan di aprire diverse schede con diversi portafogli.

È window.onblur e window.onfocus un'opzione per questo?

127
Fenton

Sì, window.onfocus e window.onblur dovrebbe funzionare per il tuo scenario:

http://www.thefutureoftheweb.com/blog/detect-browser-window-focus

109
Ryan Wright

Importante Modifica: Questa risposta è obsoleta. Da quando è stato scritto, è stata introdotta l'API di visibilità ( mdn , esempio , spec ). È il modo migliore per risolvere questo problema.


var focused = true;

window.onfocus = function() {
    focused = true;
};
window.onblur = function() {
    focused = false;
};

AFAIK, focus e blur sono tutti supportati su ... tutto. (vedi http://www.quirksmode.org/dom/events/index.html )

46
Zirak

Durante la ricerca di questo problema, ho trovato una raccomandazione che Page Visibility API dovrebbe essere usato. I browser più moderni supportano questa API secondo Can I Use: http://caniuse.com/#feat=pagevisibility .

Ecco un esempio funzionante (derivato da questo snippet ):

$(document).ready(function() {
  var hidden, visibilityState, visibilityChange;

  if (typeof document.hidden !== "undefined") {
    hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
  } else if (typeof document.msHidden !== "undefined") {
    hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
  }

  var document_hidden = document[hidden];

  document.addEventListener(visibilityChange, function() {
    if(document_hidden != document[hidden]) {
      if(document[hidden]) {
        // Document hidden
      } else {
        // Document shown
      }

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

Aggiornamento: L'esempio sopra utilizzato aveva proprietà prefissate per i browser Gecko e WebKit, ma ho rimosso tale implementazione perché questi browser offrivano l'API di visibilità della pagina senza un prefisso da un po 'di tempo. Ho mantenuto il prefisso specifico di Microsoft per rimanere compatibile con IE10.

41
Ilija

Sì, quelli dovrebbero funzionare per te. Mi hai appena ricordato questo link che ho trovato che sfrutta quelle tecniche. lettura interessante

29
Brian Glaz

Sorprendente vedere nessuno menzionato document.hasFocus

if (document.hasFocus()) console.log('Tab is active')

MDN ha più informazioni.

21
aleclarson

Lo farei in questo modo (Riferimento http://www.w3.org/TR/page-visibility/ ):

    window.onload = function() {

        // check the visiblility of the page
        var hidden, visibilityState, visibilityChange;

        if (typeof document.hidden !== "undefined") {
            hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
        }
        else if (typeof document.mozHidden !== "undefined") {
            hidden = "mozHidden", visibilityChange = "mozvisibilitychange", visibilityState = "mozVisibilityState";
        }
        else if (typeof document.msHidden !== "undefined") {
            hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
        }
        else if (typeof document.webkitHidden !== "undefined") {
            hidden = "webkitHidden", visibilityChange = "webkitvisibilitychange", visibilityState = "webkitVisibilityState";
        }


        if (typeof document.addEventListener === "undefined" || typeof hidden === "undefined") {
            // not supported
        }
        else {
            document.addEventListener(visibilityChange, function() {
                console.log("hidden: " + document[hidden]);
                console.log(document[visibilityState]);

                switch (document[visibilityState]) {
                case "visible":
                    // visible
                    break;
                case "hidden":
                    // hidden
                    break;
                }
            }, false);
        }

        if (document[visibilityState] === "visible") {
            // visible
        }

    };  
4
confile

Soluzione jQuery per browser multipli!  Raw disponibile su GitHub

Divertente e facile da usare!

Il seguente plugin eseguirà il test standard per varie versioni di IE, Chrome, Firefox, Safari, ecc. E stabilirà i metodi dichiarati di conseguenza. Si occupa anche di problemi come:

  • onblur | .blur/onfocus | .focus " duplicato" chiamate
  • la finestra perde attenzione attraverso la selezione di app alternative, come Word
    • Questo tende ad essere indesiderabile semplicemente perché, se hai una pagina di banca aperta, e l'evento onblur ti dice di mascherare la pagina, quindi se apri la calcolatrice, non puoi più vedere la pagina !
  • Non si attiva al caricamento della pagina

L'uso è semplice come: Scorri verso il basso fino a " Esegui snippet '

$.winFocus(function(event, isVisible) {
    console.log("Combo\t\t", event, isVisible);
});

//  OR Pass False boolean, and it will not trigger on load,
//  Instead, it will first trigger on first blur of current tab_window
$.winFocus(function(event, isVisible) {
    console.log("Combo\t\t", event, isVisible);
}, false);

//  OR Establish an object having methods "blur" & "focus", and/or "blurFocus"
//  (yes, you can set all 3, tho blurFocus is the only one with an 'isVisible' param)
$.winFocus({
    blur: function(event) {
        console.log("Blur\t\t", event);
    },
    focus: function(event) {
        console.log("Focus\t\t", event);
    }
});

//  OR First method becoms a "blur", second method becoms "focus"!
$.winFocus(function(event) {
    console.log("Blur\t\t", event);
},
function(event) {
    console.log("Focus\t\t", event);
});
/*    Begin Plugin    */
;;(function($){$.winFocus||($.extend({winFocus:function(){var a=!0,b=[];$(document).data("winFocus")||$(document).data("winFocus",$.winFocus.init());for(x in arguments)"object"==typeof arguments[x]?(arguments[x].blur&&$.winFocus.methods.blur.Push(arguments[x].blur),arguments[x].focus&&$.winFocus.methods.focus.Push(arguments[x].focus),arguments[x].blurFocus&&$.winFocus.methods.blurFocus.Push(arguments[x].blurFocus),arguments[x].initRun&&(a=arguments[x].initRun)):"function"==typeof arguments[x]?b.Push(arguments[x]):
"boolean"==typeof arguments[x]&&(a=arguments[x]);b&&(1==b.length?$.winFocus.methods.blurFocus.Push(b[0]):($.winFocus.methods.blur.Push(b[0]),$.winFocus.methods.focus.Push(b[1])));if(a)$.winFocus.methods.onChange()}}),$.winFocus.init=function(){$.winFocus.props.hidden in document?document.addEventListener("visibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="mozHidden")in document?document.addEventListener("mozvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden=
"webkitHidden")in document?document.addEventListener("webkitvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="msHidden")in document?document.addEventListener("msvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="onfocusin")in document?document.onfocusin=document.onfocusout=$.winFocus.methods.onChange:window.onpageshow=window.onpagehide=window.onfocus=window.onblur=$.winFocus.methods.onChange;return $.winFocus},$.winFocus.methods={blurFocus:[],blur:[],focus:[],
exeCB:function(a){$.winFocus.methods.blurFocus&&$.each($.winFocus.methods.blurFocus,function(b,c){this.apply($.winFocus,[a,!a.hidden])});a.hidden&&$.winFocus.methods.blur&&$.each($.winFocus.methods.blur,function(b,c){this.apply($.winFocus,[a])});!a.hidden&&$.winFocus.methods.focus&&$.each($.winFocus.methods.focus,function(b,c){this.apply($.winFocus,[a])})},onChange:function(a){var b={focus:!1,focusin:!1,pageshow:!1,blur:!0,focusout:!0,pagehide:!0};if(a=a||window.event)a.hidden=a.type in b?b[a.type]:
document[$.winFocus.props.hidden],$(window).data("visible",!a.hidden),$.winFocus.methods.exeCB(a);else try{$.winFocus.methods.onChange.call(document,new Event("visibilitychange"))}catch(c){}}},$.winFocus.props={hidden:"hidden"})})(jQuery);
/*    End Plugin      */

// Simple example
$(function() {
        $.winFocus(function(event, isVisible) {
                $('td tbody').empty();
                $.each(event, function(i) {
                        $('td tbody').append(
                                $('<tr />').append(
                                        $('<th />', { text: i }),
                                        $('<td />', { text: this.toString() })
                                )
                        )
                });
                if (isVisible) 
                        $("#isVisible").stop().delay(100).fadeOut('fast', function(e) {
                                $('body').addClass('visible');
                                $(this).stop().text('TRUE').fadeIn('slow');
                        });
                else {
                        $('body').removeClass('visible');
                        $("#isVisible").text('FALSE');
                }
        });
})
body { background: #AAF; }
table { width: 100%; }
table table { border-collapse: collapse; margin: 0 auto; width: auto; }
tbody > tr > th { text-align: right; }
td { width: 50%; }
th, td { padding: .1em .5em; }
td th, td td { border: 1px solid; }
.visible { background: #FFA; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h3>See Console for Event Object Returned</h3>
<table>
    <tr>
        <th><p>Is Visible?</p></th>
        <td><p id="isVisible">TRUE</p></td>
    </tr>
    <tr>
        <td colspan="2">
            <table>
                <thead>
                    <tr>
                        <th colspan="2">Event Data <span style="font-size: .8em;">{ See Console for More Details }</span></th>
                    </tr>
                </thead>
                <tbody></tbody>
            </table>
        </td>
    </tr>
</table>
2
SpYk3HH