2013-04-11 14 views
13

Wyszukałem trochę absurdalnie wysokich czasów ładowania, które zgłosił javascript mojej aplikacji, i odkryłem, że Android (i iOS) wstrzymują niektóre JavaScript wykonanie, gdy okno jest w tle lub wyświetlacz jest wyłączony.Czy w JavaScript można wykryć, kiedy ekran jest wyłączony w przeglądarkach na urządzeniach z Androidem i iOS?

Na Androidzie stwierdziłem, że mogę użyć zdarzeń window.onfocus i onblur, aby wykryć, kiedy aplikacja przełączała się na tło (i wykonanie js wkrótce zostanie wstrzymane, przynajmniej dla nowych skryptów), ale nie mogę znaleźć sposób na wykrycie, kiedy ekran jest włączony lub wyłączony. czy to możliwe?

(On Safari, miałem podobne wyniki z wyjątkiem tego onfocus i onblur nie ogień niezawodnie.)

+3

Czy wyłączanie ekranu i nie uruchamianie zdarzeń 'onblur' i' onfocus', biorąc pod uwagę, że Android zazwyczaj przechodzi na ekran blokady? Myślę, że wyłączenie go może uruchomić 'onblur', a przynajmniej obudzenie go uruchomi' onblur' (jeśli nie zostanie wyłączone), ponieważ Android wyświetli ekran blokady, a następnie po przejściu przez ekran blokady , 'onfocus' będzie strzelał od czasu przejścia z ekranu blokady do aktywnej aplikacji. Nie jestem ekspertem od Androida, ale pomyślałem, że wyrzucę tę myśl, jeśli nie sprawdziłeś. – ajp15243

+0

Cóż, mój nie testowałem, ale teraz, kiedy o tym wspomniałeś, wyłączyłem mój ekran blokady.Po prostu wracam do ostatniej aplikacji, którą otworzyłem, gdy tylko kliknę przycisk zasilania. Włączenie ekranu blokady spowodowało wyzwolenie zdarzeń związanych z ustawianiem ostrości i rozmyciem. Dzięki! –

Odpowiedz

5

Istnieje kilka opcji, aby to sprawdzić:

  1. Korzystanie Visibility API

  2. Korzystanie focus i blur zdarzenia do wykrywania przeglądarki widoczność zakładka:

 
window.addEventListener("focus", handleBrowserState.bind(context, true)); 
window.addEventListener("blur", handleBrowserState.bind(context, false)); 

function handleBrowserState(isActive){ 
    // do something 
} 
  1. Korzystanie z timerów, jak wspomniano powyżej:
+0

Hah, początkowa wersja specyfikacji widoczności strony została opublikowana około miesiąc po tym, jak opublikowałem pytanie! To wydaje się być poprawną odpowiedzią w tym momencie. –

+1

3 lata na uzyskanie poprawnej odpowiedzi :) Pracuję nad tymi samymi problemami już teraz i mam już dużo nowych informacji ... Ale wciąż mam pewne problemy z przeglądarką internetową Android (opartą na Chromium 34) - ta przeglądarka nie obsługuje zmian widoczności i żaden z opisanych powyżej sposobów nie działa ... –

11

Właśnie znalazłem dość dobre rozwiązanie dla mojego przypadku użycia:

function getTime() { 
    return (new Date()).getTime(); 
} 

var lastInterval = getTime(); 

function intervalHeartbeat() { 
    var now = getTime(); 
    var diff = now - lastInterval; 
    var offBy = diff - 1000; // 1000 = the 1 second delay I was expecting 
    lastInterval = now; 

    if(offBy > 100) { // don't trigger on small stutters less than 100ms 
     console.log('interval heartbeat - off by ' + offBy + 'ms'); 
    } 
} 

setInterval(intervalHeartbeat, 1000); 

Kiedy ekran jest wyłączony (lub JS jest wstrzymany z dowolnego powodu), następny interwał jest opóźniony do czasu wznowienia wykonywania JS. W moim kodzie mogę ustawić timery na wartość offBy i nazwać to dobrze.

W szybkich testach wszystko to działa dobrze zarówno w przeglądarce Androida 4.2.2, jak i Safari na iOS 6.1.3.

+0

Sprytny, dzięki !! –

2

co zrobisz w swoim skrypcie, gdy ekran się wyłączy? Cóż, w każdym razie można wstrzykiwać obiekty Java (http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)) w celu połączenia z działaniem i pełnomocnictwa dla wszystkich informacji wymaganych w świecie JS.

+0

Nie coś, co chcę zrobić, ale otrzymałeś uprowadzenie, ponieważ jest to dobra odpowiedź na pytanie :) –

4

Znaleziony piękny funkcję tutaj:

http://rakaz.nl/2009/09/iphone-webapps-101-detecting-essential-information-about-your-iphone.html

(function() { 
    var timestamp = new Date().getTime(); 

    function checkResume() { 
     var current = new Date().getTime(); 
     if (current - timestamp > 4000) { 
      var event = document.createEvent("Events"); 
      event.initEvent("resume", true, true); 
      document.dispatchEvent(event); 
     } 
     timestamp = current; 
    } 

    window.setInterval(checkResume, 1000); 
})(); 

Aby zarejestrować się na wydarzenie:

addEventListener("resume", function() { 
    alert('Resuming this webapp'); 
}); 

Jest to zgodne z Cordova, który również wyzwala zdarzenie resume.

Powiązane problemy