Czy istnieje sposób na wykrycie, czy okno przeglądarki nie jest obecnie aktywne?

Mam JavaScript, który wykonuje aktywność okresowo. Gdy użytkownik nie patrzy na witrynę (tj. okno lub karta nie ma ostrości), dobrze byłoby nie uruchamiać.

Czy istnieje sposób, aby to zrobić za pomocą JavaScript?

Mój punkt odniesienia: Gmail Chat odtwarza dźwięk, jeśli okno, którego używasz, nie jest aktywne.

Author: Mark Amery, 2009-06-29

18 answers

Od czasu napisania tej odpowiedzi, Nowa Specyfikacja osiągnęła zalecenie status dzięki W3C. Page Visibility API (on MDN ) pozwala nam teraz dokładniej wykryć, kiedy strona jest ukryta dla użytkownika.

Bieżąca obsługa przeglądarki:

  • Chrome 13+
  • Internet Explorer 10+
  • Firefox 10+
  • Opera 12.10+ [Czytaj notatki ]

Poniższy kod wykorzystuje API, wracając do mniej niezawodnej metody blur/focus w niekompatybilnych przeglądarkach.

(function() {
  var hidden = "hidden";

  // Standards:
  if (hidden in document)
    document.addEventListener("visibilitychange", onchange);
  else if ((hidden = "mozHidden") in document)
    document.addEventListener("mozvisibilitychange", onchange);
  else if ((hidden = "webkitHidden") in document)
    document.addEventListener("webkitvisibilitychange", onchange);
  else if ((hidden = "msHidden") in document)
    document.addEventListener("msvisibilitychange", onchange);
  // IE 9 and lower:
  else if ("onfocusin" in document)
    document.onfocusin = document.onfocusout = onchange;
  // All others:
  else
    window.onpageshow = window.onpagehide
    = window.onfocus = window.onblur = onchange;

  function onchange (evt) {
    var v = "visible", h = "hidden",
        evtMap = {
          focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
        };

    evt = evt || window.event;
    if (evt.type in evtMap)
      document.body.className = evtMap[evt.type];
    else
      document.body.className = this[hidden] ? "hidden" : "visible";
  }

  // set the initial state (but only if browser supports the Page Visibility API)
  if( document[hidden] !== undefined )
    onchange({type: document[hidden] ? "blur" : "focus"});
})();

onfocusin i onfocusoutwymagane dla IE 9 i niższych, podczas gdy wszystkie inne korzystają z onfocus i onblur, z wyjątkiem iOS, który używa onpageshow i onpagehide.

 601
Author: Andy E,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-22 09:45:01

Użyłbym jQuery, bo wtedy wystarczy tylko to:

$(window).blur(function(){
  //your code here
});
$(window).focus(function(){
  //your code
});
A przynajmniej mi się udało.
 121
Author: Carson Wright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-09 06:34:31

Są 3 typowe metody używane do określenia, czy użytkownik może zobaczyć stronę HTML, jednak żadna z nich nie działa idealnie:

  • Ma to zrobić W3C page Visibility API (obsługiwane od: Firefox 10, MSIE 10, Chrome 13). Jednak ten API wywołuje zdarzenia tylko wtedy, gdy karta przeglądarki jest w pełni nadpisana(np. gdy użytkownik zmienia kartę z jednej na drugą). Interfejs API nie generuje zdarzeń, gdy widoczność nie może być określona ze 100% dokładnością (np. Alt + Tab aby przejść do innej aplikacji).

  • Używanie metod opartych na fokusie / rozmyciu daje dużo fałszywych wyników. Na przykład, jeśli użytkownik wyświetli mniejsze okno na górze okna przeglądarki, okno przeglądarki straci fokus (onblur podniesiony), ale użytkownik nadal jest w stanie go zobaczyć (więc nadal trzeba go odświeżyć). Zobacz też http://javascript.info/tutorial/focus

  • poleganie na aktywności użytkownika (ruch myszki, kliknięcia, klawisz wpisany) daje dużo fałszywych pozytywnych też. Pomyśl o tym samym przypadku, co powyżej, lub użytkownik oglądający film.

Aby poprawić opisane powyżej niedoskonałe zachowania, używam kombinacji 3 metod: W3C Visibility API, następnie focus/blur i user activity methods w celu zmniejszenia liczby fałszywych pozytywnych wyników. Pozwala to na zarządzanie następującymi zdarzeniami:

    W 2008 roku firma została założona przez firmę w celu zapewnienia klientom wysokiej jakości usług.]}
  • strona ukryte przez inne okno, np. ze względu na Alt+Tab (probabilistic = Nie 100% dokładne)
  • Uwaga użytkownika potencjalnie nie koncentruje się na stronie HTML (probabilistyczne = Nie 100% dokładne)

Tak to działa: gdy dokument traci ostrość, aktywność użytkownika (np. ruch myszy) na dokumencie jest monitorowana w celu określenia, czy okno jest widoczne, czy nie. Prawdopodobieństwo widoczności strony jest odwrotnie proporcjonalne do czasu ostatniej aktywności użytkownika na stronie: jeśli użytkownik nie wykonuje żadnej aktywności na dokumencie przez długi czas, Strona najprawdopodobniej nie jest widoczna. Poniższy kod naśladuje interfejs API widoczności stron W3C: zachowuje się tak samo, ale ma niewielki wskaźnik fałszywie dodatni. Ma tę zaletę, że jest multibrowser (testowany na Firefox 5, Firefox 10, MSIE 9, MSIE 7, Safari 5, Chrome 9).


    <div id="x"></div>

    <script>
    /**
    Registers the handler to the event for the given object.
    @param obj the object which will raise the event
    @param evType the event type: click, keypress, mouseover, ...
    @param fn the event handler function
    @param isCapturing set the event mode (true = capturing event, false = bubbling event)
    @return true if the event handler has been attached correctly
    */
    function addEvent(obj, evType, fn, isCapturing){
      if (isCapturing==null) isCapturing=false; 
      if (obj.addEventListener){
        // Firefox
        obj.addEventListener(evType, fn, isCapturing);
        return true;
      } else if (obj.attachEvent){
        // MSIE
        var r = obj.attachEvent('on'+evType, fn);
        return r;
      } else {
        return false;
      }
    }

    // register to the potential page visibility change
    addEvent(document, "potentialvisilitychange", function(event) {
      document.getElementById("x").innerHTML+="potentialVisilityChange: potentialHidden="+document.potentialHidden+", document.potentiallyHiddenSince="+document.potentiallyHiddenSince+" s<br>";
    });

    // register to the W3C Page Visibility API
    var hidden=null;
    var visibilityChange=null;
    if (typeof document.mozHidden !== "undefined") {
      hidden="mozHidden";
      visibilityChange="mozvisibilitychange";
    } else if (typeof document.msHidden !== "undefined") {
      hidden="msHidden";
      visibilityChange="msvisibilitychange";
    } else if (typeof document.webkitHidden!=="undefined") {
      hidden="webkitHidden";
      visibilityChange="webkitvisibilitychange";
    } else if (typeof document.hidden !=="hidden") {
      hidden="hidden";
      visibilityChange="visibilitychange";
    }
    if (hidden!=null && visibilityChange!=null) {
      addEvent(document, visibilityChange, function(event) {
        document.getElementById("x").innerHTML+=visibilityChange+": "+hidden+"="+document[hidden]+"<br>";
      });
    }


    var potentialPageVisibility = {
      pageVisibilityChangeThreshold:3*3600, // in seconds
      init:function() {
        function setAsNotHidden() {
          var dispatchEventRequired=document.potentialHidden;
          document.potentialHidden=false;
          document.potentiallyHiddenSince=0;
          if (dispatchEventRequired) dispatchPageVisibilityChangeEvent();
        }

        function initPotentiallyHiddenDetection() {
          if (!hasFocusLocal) {
            // the window does not has the focus => check for  user activity in the window
            lastActionDate=new Date();
            if (timeoutHandler!=null) {
              clearTimeout(timeoutHandler);
            }
            timeoutHandler = setTimeout(checkPageVisibility, potentialPageVisibility.pageVisibilityChangeThreshold*1000+100); // +100 ms to avoid rounding issues under Firefox
          }
        }

        function dispatchPageVisibilityChangeEvent() {
          unifiedVisilityChangeEventDispatchAllowed=false;
          var evt = document.createEvent("Event");
          evt.initEvent("potentialvisilitychange", true, true);
          document.dispatchEvent(evt);
        }

        function checkPageVisibility() {
          var potentialHiddenDuration=(hasFocusLocal || lastActionDate==null?0:Math.floor((new Date().getTime()-lastActionDate.getTime())/1000));
                                        document.potentiallyHiddenSince=potentialHiddenDuration;
          if (potentialHiddenDuration>=potentialPageVisibility.pageVisibilityChangeThreshold && !document.potentialHidden) {
            // page visibility change threshold raiched => raise the even
            document.potentialHidden=true;
            dispatchPageVisibilityChangeEvent();
          }
        }

        var lastActionDate=null;
        var hasFocusLocal=true;
        var hasMouseOver=true;
        document.potentialHidden=false;
        document.potentiallyHiddenSince=0;
        var timeoutHandler = null;

        addEvent(document, "pageshow", function(event) {
          document.getElementById("x").innerHTML+="pageshow/doc:<br>";
        });
        addEvent(document, "pagehide", function(event) {
          document.getElementById("x").innerHTML+="pagehide/doc:<br>";
        });
        addEvent(window, "pageshow", function(event) {
          document.getElementById("x").innerHTML+="pageshow/win:<br>"; // raised when the page first shows
        });
        addEvent(window, "pagehide", function(event) {
          document.getElementById("x").innerHTML+="pagehide/win:<br>"; // not raised
        });
        addEvent(document, "mousemove", function(event) {
          lastActionDate=new Date();
        });
        addEvent(document, "mouseover", function(event) {
          hasMouseOver=true;
          setAsNotHidden();
        });
        addEvent(document, "mouseout", function(event) {
          hasMouseOver=false;
          initPotentiallyHiddenDetection();
        });
        addEvent(window, "blur", function(event) {
          hasFocusLocal=false;
          initPotentiallyHiddenDetection();
        });
        addEvent(window, "focus", function(event) {
          hasFocusLocal=true;
          setAsNotHidden();
        });
        setAsNotHidden();
      }
    }

    potentialPageVisibility.pageVisibilityChangeThreshold=4; // 4 seconds for testing
    potentialPageVisibility.init();
    </script>

Ponieważ obecnie nie ma działającego rozwiązania między przeglądarkami bez fałszywych alarmów, lepiej zastanów się dwa razy nad wyłączeniem okresowej aktywności w sieci miejscu.

 41
Author: Julien Kronegg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-01 22:02:58

Istnieje porządna Biblioteka dostępna na Githubie:

Https://github.com/serkanyersen/ifvisible.js

Przykład:

// If page is visible right now
if( ifvisible.now() ){
  // Display pop-up
  openPopUp();
}

Przetestowałem wersję 1.0.1 na wszystkich przeglądarkach, które mam i mogę potwierdzić, że działa:

  • IE9, IE10
  • FF 26.0
  • Chrome 34.0

... i prawdopodobnie wszystkie nowsze wersje.

Nie działa w pełni z:

  • IE8 - zawsze oznacza, że zakładka/okno jest aktualnie aktywna (.now() zawsze returns true for me)
 23
Author: Piotr De,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-16 12:03:40

Tworzę Czat Comet dla mojej aplikacji, a gdy otrzymam wiadomość od innego użytkownika, używam:

if(new_message){
    if(!document.hasFocus()){
        audio.play();
        document.title="Have new messages";
    }
    else{
        audio.stop();
        document.title="Application Name";
    } 
}
 11
Author: infinito84,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-30 14:31:20

To naprawdę trudne. Wydaje się, że nie ma rozwiązania, biorąc pod uwagę następujące wymagania.

  • strona zawiera iframes, nad którymi nie masz kontroli
  • chcesz śledzić zmianę stanu widoczności niezależnie od zmiany wywołanej przez zmianę karty (ctrl+tab) lub zmianę okna (alt+tab)

Dzieje się tak ponieważ:

  • Interfejs API widoczności strony może niezawodnie informować o zmianie karty (nawet w przypadku ramek iFrame), ale nie może informować o zmianie użytkownika okna.
  • nasłuchiwanie zdarzeń rozmycie/ostrość okna może wykryć alt + tabs i ctrl + tabs, o ile ramka iframe nie ma ostrości.

Biorąc pod uwagę te ograniczenia, możliwe jest wdrożenie rozwiązania, które łączy - API widoczności strony - rozmycie okna/ostrość - dokument.activeElement

To jest w stanie:

  • 1) ctrl + tab gdy Strona nadrzędna ma fokus: tak
  • 2) ctrl+tab gdy iframe ma fokus: tak
  • 3) alt + tab gdy Strona nadrzędna ma fokus: Tak
  • 4) alt + tab gdy iframe ma focus: NO

Gdy ramka iframe ma fokus, zdarzenia rozmycie/ostrość nie są wywoływane w ogóle, a interfejs API widoczności strony nie zostanie uruchomiony na alt + tab.

Zbudowałem na rozwiązaniu @ AndyE i zaimplementowałem to (prawie dobre) rozwiązanie tutaj: https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test1.html (przepraszam, miałem pewne problemy z JSFiddle).

To jest również dostępne na Github: https://github.com/qmagico/estante-components

To działa na chrome / chromium. Działa na Firefoksie, tyle że nie ładuje zawartości iframe (jakiś pomysł dlaczego?)

W każdym razie, aby rozwiązać ostatni problem (4), jedynym sposobem, aby to zrobić, jest nasłuchiwanie rozmycia/fokusu zdarzeń na ramce iframe. Jeśli masz pewną kontrolę nad ramkami iframes, możesz użyć API postMessage, aby to zrobić to.

Https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test2.html

Nadal nie testowałem tego z wystarczającą ilością przeglądarek. Jeśli znajdziesz więcej informacji o tym, gdzie to nie działa, daj mi znać w komentarzach poniżej.

 7
Author: Tony Lâmpada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-17 17:43:48

Za pomocą : Page Visibility API

document.addEventListener( 'visibilitychange' , function() {
    if (document.hidden) {
        console.log('bye');
    } else {
        console.log('well back');
    }
}, false );

Mogę użyć ? http://caniuse.com/#feat=pagevisibility

 7
Author: l2aelba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-05 08:29:01

Zacząłem używać community wiki answer, ale zdałem sobie sprawę, że nie wykrywa zdarzeń alt-tab w Chrome. Dzieje się tak, ponieważ używa pierwszego dostępnego źródła zdarzeń, a w tym przypadku jest to interfejs API widoczności strony, który w Chrome wydaje się nie śledzić alt-tabbing.

Postanowiłem nieco zmodyfikować skrypt, aby śledzić Wszystkie możliwe zdarzenia dla zmiany ostrości strony. Oto funkcja, którą możesz wrzucić:

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;
};

Użyj go tak:

onVisibilityChange(function(visible) {
    console.log('the page is now', visible ? 'focused' : 'unfocused');
});
 6
Author: Daniel Buckmaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-02 01:18:15
var visibilityChange = (function (window) {
    var inView = false;
    return function (fn) {
        window.onfocus = window.onblur = window.onpageshow = window.onpagehide = function (e) {
            if ({focus:1, pageshow:1}[e.type]) {
                if (inView) return;
                fn("visible");
                inView = true;
            } else if (inView) {
                fn("hidden");
                inView = false;
            }
        };
    };
}(this));

visibilityChange(function (state) {
    console.log(state);
});

Http://jsfiddle.net/ARTsinn/JTxQY/

 4
Author: yckart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-13 13:08:11

U można użyć:

(function () {

    var requiredResolution = 10; // ms
    var checkInterval = 1000; // ms
    var tolerance = 20; // percent


    var counter = 0;
    var expected = checkInterval / requiredResolution;
    //console.log('expected:', expected);

    window.setInterval(function () {
        counter++;
    }, requiredResolution);

    window.setInterval(function () {
        var deviation = 100 * Math.abs(1 - counter / expected);
        // console.log('is:', counter, '(off by', deviation , '%)');
        if (deviation > tolerance) {
            console.warn('Timer resolution not sufficient!');
        }
        counter = 0;
    }, checkInterval);

})();
 3
Author: maryam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-10 10:58:48

W HTML 5 Możesz również użyć:

  • onpageshow: skrypt do uruchomienia, gdy okno stanie się widoczne
  • onpagehide: skrypt do uruchomienia, gdy okno jest ukryte

Zobacz:

 3
Author: roberkules,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-06 12:17:41

Nieco bardziej skomplikowanym sposobem byłoby użycie setInterval() do sprawdzenia pozycji myszy i porównania do ostatniego sprawdzenia. Jeśli mysz nie porusza się w określonym czasie, użytkownik prawdopodobnie jest bezczynny.

ma to dodatkową zaletę polegającą na informowaniu, czy użytkownik jest bezczynny, zamiast tylko sprawdzania, czy okno nie jest aktywne.

Jak Wiele osób zauważyło, nie zawsze jest to dobry sposób na sprawdzenie, czy okno użytkownika lub przeglądarki jest bezczynne, ponieważ użytkownik może nawet nie używać mysz lub ogląda film lub podobne. Sugeruję tylko jeden możliwy sposób na sprawdzenie bezczynności.

 2
Author: Austin Hyde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-01 02:31:53

Jest to adaptacja odpowiedzi Andy ' ego E.

Spowoduje to wykonanie zadania np. odświeżanie strony co 30 sekund, ale tylko wtedy, gdy strona jest widoczna i skupiona.

Jeśli widoczność nie może zostać wykryta, zostanie użyta tylko ostrość.

Jeśli użytkownik skupia stronę, to zostanie ona natychmiast zaktualizowana

Strona nie zaktualizuje się ponownie do 30 sekund po wywołaniu ajax

var windowFocused = true;
var timeOut2 = null;

$(function(){
  $.ajaxSetup ({
    cache: false
  });
  $("#content").ajaxComplete(function(event,request, settings){
       set_refresh_page(); // ajax call has just been made, so page doesn't need updating again for 30 seconds
   });
  // check visibility and focus of window, so as not to keep updating unnecessarily
  (function() {
      var hidden, change, vis = {
              hidden: "visibilitychange",
              mozHidden: "mozvisibilitychange",
              webkitHidden: "webkitvisibilitychange",
              msHidden: "msvisibilitychange",
              oHidden: "ovisibilitychange" /* not currently supported */
          };
      for (hidden in vis) {
          if (vis.hasOwnProperty(hidden) && hidden in document) {
              change = vis[hidden];
              break;
          }
      }
      document.body.className="visible";
      if (change){     // this will check the tab visibility instead of window focus
          document.addEventListener(change, onchange,false);
      }

      if(navigator.appName == "Microsoft Internet Explorer")
         window.onfocus = document.onfocusin = document.onfocusout = onchangeFocus
      else
         window.onfocus = window.onblur = onchangeFocus;

      function onchangeFocus(evt){
        evt = evt || window.event;
        if (evt.type == "focus" || evt.type == "focusin"){
          windowFocused=true; 
        }
        else if (evt.type == "blur" || evt.type == "focusout"){
          windowFocused=false;
        }
        if (evt.type == "focus"){
          update_page();  // only update using window.onfocus, because document.onfocusin can trigger on every click
        }

      }

      function onchange () {
        document.body.className = this[hidden] ? "hidden" : "visible";
        update_page();
      }

      function update_page(){
        if(windowFocused&&(document.body.className=="visible")){
          set_refresh_page(1000);
        }
      }


  })();
  set_refresh_page();
})

function get_date_time_string(){
  var d = new Date();
  var dT = [];
  dT.push(d.getDate());
  dT.push(d.getMonth())
  dT.push(d.getFullYear());
  dT.push(d.getHours());
  dT.push(d.getMinutes());
  dT.push(d.getSeconds());
  dT.push(d.getMilliseconds());
  return dT.join('_');
}

function do_refresh_page(){

// do tasks here

// e.g. some ajax call to update part of the page.

// (date time parameter will probably force the server not to cache)

//      $.ajax({
//        type: "POST",
//        url: "someUrl.php",
//        data: "t=" + get_date_time_string()+"&task=update",
//        success: function(html){
//          $('#content').html(html);
//        }
//      });

}

function set_refresh_page(interval){
  interval = typeof interval !== 'undefined' ? interval : 30000; // default time = 30 seconds
  if(timeOut2 != null) clearTimeout(timeOut2);
  timeOut2 = setTimeout(function(){
    if((document.body.className=="visible")&&windowFocused){
      do_refresh_page();
    }
    set_refresh_page();
  }, interval);
}
 2
Author: roger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-18 08:06:14

Dla rozwiązania bez jQuery sprawdź widoczność.js , który dostarcza informacji o trzech stanach strony

visible    ... page is visible
hidden     ... page is not visible
prerender  ... page is being prerendered by the browser

A także wygoda-owijarki do setInterval

/* Perform action every second if visible */
Visibility.every(1000, function () {
    action();
});

/* Perform action every second if visible, every 60 sec if not visible */
Visibility.every(1000, 60*1000, function () {
    action();
});

Alternatywa dla starszych przeglądarek (IE

 1
Author: Niko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-20 10:46:20

Dla kątowych.js, oto dyrektywa (oparta na zaakceptowanej odpowiedzi), która pozwoli Twojemu kontrolerowi zareagować na zmianę widoczności:

myApp.directive('reactOnWindowFocus', function($parse) {
    return {
        restrict: "A",
        link: function(scope, element, attrs) {
            var hidden = "hidden";
            var currentlyVisible = true;
            var functionOrExpression = $parse(attrs.reactOnWindowFocus);

          // Standards:
          if (hidden in document)
            document.addEventListener("visibilitychange", onchange);
          else if ((hidden = "mozHidden") in document)
            document.addEventListener("mozvisibilitychange", onchange);
          else if ((hidden = "webkitHidden") in document)
            document.addEventListener("webkitvisibilitychange", onchange);
          else if ((hidden = "msHidden") in document)
            document.addEventListener("msvisibilitychange", onchange);
          else if ("onfocusin" in document) {
                // IE 9 and lower:
            document.onfocusin = onshow;
                document.onfocusout = onhide;
          } else {
                // All others:
            window.onpageshow = window.onfocus = onshow;
                window.onpagehide = window.onblur = onhide;
            }

          function onchange (evt) {
                //occurs both on leaving and on returning
                currentlyVisible = !currentlyVisible;
                doSomethingIfAppropriate();
          }

            function onshow(evt) {
                //for older browsers
                currentlyVisible = true;
                doSomethingIfAppropriate();
            }

            function onhide(evt) {
                //for older browsers
                currentlyVisible = false;
                doSomethingIfAppropriate();
            }

            function doSomethingIfAppropriate() {
                if (currentlyVisible) {
                    //trigger angular digest cycle in this scope
                    scope.$apply(function() {
                        functionOrExpression(scope);
                    });
                }
            }
        }
    };

});

Możesz go użyć w następujący sposób: <div react-on-window-focus="refresh()">, Gdzie {[2] } jest funkcją scope w zakresie dowolnego kontrolera w zakresie.

 1
Author: Steve Campbell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-26 17:38:38

To działa u mnie na chrome 67, firefox 67,

if(!document.hasFocus()) {
    // do stuff
}
 1
Author: El Programmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-18 12:29:20

Jeśli chcesz działać na cały rozmycie przeglądarki : Jak skomentowałem, jeśli przeglądarka traci ostrość, żadne z sugerowanych zdarzeń nie odpali. Moim pomysłem jest odliczanie w pętli i zresetowanie licznika, jeśli pożar zdarzenia. Jeśli licznik osiągnie limit, robię lokalizację.href na inną stronę. To również odpala się, jeśli pracujesz na dev-tools.

var iput=document.getElementById("hiddenInput");
   ,count=1
   ;
function check(){
         count++;
         if(count%2===0){
           iput.focus();
         }
         else{
           iput.blur();
         }
         iput.value=count;  
         if(count>3){
           location.href="http://Nirwana.com";
         }              
         setTimeout(function(){check()},1000);
}   
iput.onblur=function(){count=1}
iput.onfocus=function(){count=1}
check();

Jest to projekt udany przetestowany na FF.

 0
Author: B.F.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-04 23:28:26

Chciałem tylko dodać: Pytanie nie jest jasno napisane. "Gdy użytkownik nie patrzy na witrynę (tzn. okno lub karta nie mają Fokusa)..."

Mogę patrzeć na stronę, gdy nie jest skupiona. Większość systemów desktopowych jest w stanie wyświetlać okna równolegle:)

Dlatego API widoczności strony jest prawdopodobnie właściwą odpowiedzią, ponieważ zapobiega aktualizacji witryny, gdy "użytkownik nie jest w stanie zobaczyć aktualizacji", które mogą być bardzo różne od "zakładka nie ma ostrości".

 0
Author: HolgerJeromin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-27 14:09:58