Es gibt drei typische Methoden, mit denen ermittelt wird, ob der Benutzer die HTML-Seite sehen kann. Keine davon funktioniert jedoch einwandfrei:
Die W3C Page Visibility API soll dies tun (unterstützt seit: Firefox 10, MSIE 10, Chrome 13). Diese API löst jedoch nur Ereignisse aus, wenn die Browser-Registerkarte vollständig überschrieben ist (z. B. wenn der Benutzer von einer Registerkarte zu einer anderen wechselt). Die API löst keine Ereignisse aus, wenn die Sichtbarkeit nicht mit 100% iger Genauigkeit bestimmt werden kann (z. B. Alt + Tab, um zu einer anderen Anwendung zu wechseln).
Die Verwendung von auf Fokus / Unschärfe basierenden Methoden führt zu vielen falsch positiven Ergebnissen. Wenn der Benutzer beispielsweise ein kleineres Fenster über dem Browserfenster anzeigt, verliert das Browserfenster den Fokus ( onblur
angehoben), der Benutzer kann ihn jedoch weiterhin sehen (daher muss er noch aktualisiert werden). Siehe auch http://javascript.info/tutorial/focus
- Wenn Sie sich auf Benutzeraktivitäten verlassen (Mausbewegung, Klicks, Eingabe der Taste), erhalten Sie auch viele falsch positive Ergebnisse. Stellen Sie sich den gleichen Fall wie oben vor oder einen Benutzer, der sich ein Video ansieht.
Um das oben beschriebene unvollständige Verhalten zu verbessern, verwende ich eine Kombination der drei Methoden: W3C-Sichtbarkeits-API, dann Fokus- / Unschärfe- und Benutzeraktivitätsmethoden, um die Falsch-Positiv-Rate zu reduzieren. Auf diese Weise können die folgenden Ereignisse verwaltet werden:
- Ändern der Browser-Registerkarte in eine andere (100% Genauigkeit dank der W3C-API für Seitensichtbarkeit)
- Seite möglicherweise von einem anderen Fenster ausgeblendet, z. B. aufgrund von Alt + Tab (probabilistisch = nicht 100% genau)
- Die Aufmerksamkeit des Benutzers ist möglicherweise nicht auf die HTML-Seite gerichtet (probabilistisch = nicht 100% genau).
So funktioniert es: Wenn das Dokument den Fokus verliert, wird die Benutzeraktivität (z. B. Mausbewegung) des Dokuments überwacht, um festzustellen, ob das Fenster sichtbar ist oder nicht. Die Wahrscheinlichkeit der Seitensichtbarkeit ist umgekehrt proportional zum Zeitpunkt der letzten Benutzeraktivität auf der Seite: Wenn der Benutzer längere Zeit keine Aktivität im Dokument ausführt, ist die Seite höchstwahrscheinlich nicht sichtbar. Der folgende Code ahmt die W3C-Sichtbarkeits-API nach: Sie verhält sich genauso, weist jedoch eine geringe Falsch-Positiv-Rate auf. Es hat den Vorteil, Multibrowser zu sein (getestet auf Firefox 5, Firefox 10, MSIE 9, MSIE 7, Safari 5, Chrome 9).
<div id = "x"> </ div>
<script>
/ **
Registriert den Handler für das Ereignis für das angegebene Objekt.
@param obj das Objekt, das das Ereignis auslöst
@param evTyp der Ereignistyp: Klicken, Tastendruck, Mouseover, ...
@param fn die Event-Handler-Funktion
@param isCapturing legt den Ereignismodus fest (true = Ereignis erfassen, false = sprudelndes Ereignis)
@return true, wenn der Ereignishandler korrekt angehängt wurde
* /
Funktion addEvent (obj, evType, fn, isCapturing) {
if (isCapturing == null) isCapturing = false;
if (obj.addEventListener) {
// Feuerfuchs
obj.addEventListener (evType, fn, isCapturing);
return true;
} else if (obj.attachEvent) {
// MSIE
var r = obj.attachEvent ('on' + evType, fn);
return r;
} else {
falsch zurückgeben;
}}
}}
// Registriere dich für die mögliche Änderung der Sichtbarkeit der Seite
addEvent (Dokument, "Potentialvisilitychange", Funktion (Ereignis) {
document.getElementById ("x"). innerHTML + = "PotentialVisilityChange: PotentialHidden =" + document.potentialHidden + ", document.potentialHiddenSince =" + document.potentialHiddenSince + "s <br>";
});
// Registrieren Sie sich bei der W3C Page Visibility API
var hidden = null;
var sichtbarkeitsänderung = null;
if (typeof document.mozHidden! == "undefined") {
hidden = "mozHidden";
sichtbarkeitsänderung = "mozvisibilitychange";
} else if (typeof document.msHidden! == "undefined") {
hidden = "msHidden";
sichtbarkeitsänderung = "msvisibilitychange";
} else if (typeof document.webkitHidden! == "undefined") {
hidden = "webkitHidden";
sichtbarkeitsänderung = "webkitvisibilitychange";
} else if (typeof document.hidden! == "hidden") {
versteckt = "versteckt";
sichtbarkeitsänderung = "sichtbarkeitsänderung";
}}
if (hidden! = null && sichtbarkeitsänderung! = null) {
addEvent (Dokument, Sichtbarkeitsänderung, Funktion (Ereignis) {
document.getElementById ("x"). innerHTML + = sichtbarkeitsänderung + ":" + hidden + "=" + document [hidden] + "<br>";
});
}}
var PotentialPageVisibility = {
pageVisibilityChangeThreshold: 3 * 3600, // in Sekunden
init: function () {
Funktion setAsNotHidden () {
var dispatchEventRequired = document.potentialHidden;
document.potentialHidden = false;
document.potentialHiddenSince = 0;
if (dispatchEventRequired) dispatchPageVisibilityChangeEvent ();
}}
Funktion initPotentialHiddenDetection () {
if (! hasFocusLocal) {
// Das Fenster hat nicht den Fokus => Auf Benutzeraktivität im Fenster prüfen
lastActionDate = new Date ();
if (timeoutHandler! = null) {
clearTimeout (timeoutHandler);
}}
timeoutHandler = setTimeout (checkPageVisibility, PotentialPageVisibility.pageVisibilityChangeThreshold * 1000 + 100); // +100 ms, um Rundungsprobleme unter Firefox zu vermeiden
}}
}}
Funktion dispatchPageVisibilityChangeEvent () {
unifiedVisilityChangeEventDispatchAllowed = false;
var evt = document.createEvent ("Ereignis");
evt.initEvent ("potentielle Sichtbarkeitsänderung", wahr, wahr);
document.dispatchEvent (evt);
}}
Funktion checkPageVisibility () {
var PotentialHiddenDuration = (hasFocusLocal || lastActionDate == null? 0: Math.floor ((neues Datum (). getTime () - lastActionDate.getTime ()) / 1000));
document.potentialHiddenSince = PotentialHiddenDuration;
if (PotentialHiddenDuration> = PotentialPageVisibility.pageVisibilityChangeThreshold &&! document.potentialHidden) {
// Schwellenwert für Änderung der Sichtbarkeit der Seite erhöht => Erhöhen Sie die Gerade
document.potentialHidden = true;
dispatchPageVisibilityChangeEvent ();
}}
}}
var lastActionDate = null;
var hasFocusLocal = true;
var hasMouseOver = true;
document.potentialHidden = false;
document.potentialHiddenSince = 0;
var timeoutHandler = null;
addEvent (Dokument, "Pageshow", Funktion (Ereignis) {
document.getElementById ("x"). innerHTML + = "pageshow / doc: <br>";
});
addEvent (Dokument, "Seitenhaut", Funktion (Ereignis) {
document.getElementById ("x"). innerHTML + = "pagehide / doc: <br>";
});
addEvent (Fenster, "pageshow", Funktion (Ereignis) {
document.getElementById ("x"). innerHTML + = "pageshow / win: <br>"; // wird ausgelöst, wenn die Seite zum ersten Mal angezeigt wird
});
addEvent (Fenster, "Seitenhaut", Funktion (Ereignis) {
document.getElementById ("x"). innerHTML + = "pagehide / win: <br>"; // nicht ausgelöst
});
addEvent (Dokument, "Mausbewegung", Funktion (Ereignis) {
lastActionDate = new Date ();
});
addEvent (Dokument, "Mouseover", Funktion (Ereignis) {
hasMouseOver = true;
setAsNotHidden ();
});
addEvent (Dokument, "Mouseout", Funktion (Ereignis) {
hasMouseOver = false;
initPotentialHiddenDetection ();
});
addEvent (Fenster, "Unschärfe", Funktion (Ereignis) {
hasFocusLocal = false;
initPotentialHiddenDetection ();
});
addEvent (Fenster, "Fokus", Funktion (Ereignis) {
hasFocusLocal = true;
setAsNotHidden ();
});
setAsNotHidden ();
}}
}}
PotentialPageVisibility.pageVisibilityChangeThreshold = 4; // 4 Sekunden zum Testen
PotentialPageVisibility.init ();
</ script>
Da es derzeit keine funktionierende browserübergreifende Lösung ohne falsches Positiv gibt, sollten Sie zweimal überlegen, ob Sie regelmäßige Aktivitäten auf Ihrer Website deaktivieren möchten.
requestAnimationFrame
API oder verwenden Sie die moderne Funktion, mit der die Häufigkeit vonsetTimeout
/setInterval
verringert wird, wenn das Fenster nicht sichtbar ist (z. B. 1 Sekunde in Chrome).