Mit der Screen Capture API kann der Nutzer einen Tab, ein Fenster oder einen Bildschirm auswählen, der als Medienstream erfasst werden soll. Dieser Stream kann dann aufgezeichnet oder über das Netzwerk mit anderen geteilt werden. In dieser Dokumentation wird der bedingte Fokus beschrieben, ein Mechanismus für Web-Apps, mit dem gesteuert werden kann, ob der erfasste Tab oder das erfasste Fenster beim Start der Aufnahme den Fokus erhält oder ob der Fokus auf der Seite bleibt, die erfasst wird.
Unterstützte Browser
Der bedingte Fokus ist seit Chrome 109 verfügbar.
Hintergrund
Wenn eine Webanwendung mit der Erfassung eines Tabs oder Fensters beginnt, muss der Browser eine Entscheidung treffen: Soll die erfasste Oberfläche in den Vordergrund gebracht werden oder soll der Fokus auf der Seite bleiben, die erfasst wird? Die Antwort hängt davon ab, warum getDisplayMedia()
aufgerufen wurde, und von der Oberfläche, die der Nutzer auswählt.
Stellen Sie sich eine hypothetische Webanwendung für Videokonferenzen vor. Wenn die Webanwendung track.getSettings().displaySurface
liest und möglicherweise den Capture Handle untersucht, kann sie erkennen, was der Nutzer freigegeben hat. Dann:
- Wenn der Tab oder das Fenster, das aufgenommen wird, per Fernzugriff gesteuert werden kann, halten Sie die Videokonferenz im Fokus.
- Andernfalls legen Sie den Fokus auf den Tab oder das Fenster, das Sie aufnehmen möchten.
Im Beispiel oben würde der Fokus der Web-App für Videokonferenzen bei der Freigabe einer Präsentation beibehalten, sodass der Nutzer die Folien aus der Ferne durchblättern kann. Wenn der Nutzer jedoch einen Texteditor freigibt, wechselt der Fokus der Web-App für Videokonferenzen sofort zum aufgenommenen Tab oder Fenster.
Conditional Focus API verwenden
Instanziere eine CaptureController
und übergebe sie an getDisplayMedia()
. Wenn Sie setFocusBehavior()
sofort nach der Auflösung des zurückgegebenen Versprechens getDiplayMedia()
aufrufen, können Sie festlegen, ob der erfasste Tab oder das erfasste Fenster den Fokus erhält oder nicht. Dies ist nur möglich, wenn der Nutzer einen Tab oder ein Fenster freigegeben hat.
const controller = new CaptureController();
// Prompt the user to share a tab, a window or a screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
const [track] = stream.getVideoTracks();
const displaySurface = track.getSettings().displaySurface;
if (displaySurface == "browser") {
// Focus the captured tab.
controller.setFocusBehavior("focus-captured-surface");
} else if (displaySurface == "window") {
// Do not move focus to the captured window.
// Keep the capturing page focused.
controller.setFocusBehavior("focus-capturing-application");
}
Bei der Entscheidung, ob Sie den Fokus festlegen möchten, können Sie den Capture-Griff berücksichtigen.
// Retain focus if capturing a tab dialed to example.com.
// Focus anything else.
const origin = track.getCaptureHandle().origin;
if (displaySurface == "browser" && origin == "https://example.com") {
controller.setFocusBehavior("focus-capturing-application");
} else if (displaySurface != "monitor") {
controller.setFocusBehavior("focus-captured-surface");
}
Es ist sogar möglich, vor dem Aufrufen von getDisplayMedia()
zu entscheiden, ob der Fokus gesetzt werden soll.
// Focus the captured tab or window when capture starts.
const controller = new CaptureController();
controller.setFocusBehavior("focus-captured-surface");
// Prompt the user to share their screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
Sie können setFocusBehavior()
beliebig oft vor oder höchstens einmal direkt nach der Auflösung des Versprechens aufrufen. Die letzte Aufrufe überschreibt alle vorherigen Aufrufe.
Genauer gesagt:
– Das von getDisplayMedia()
zurückgegebene Versprechen wird in einem Mikrotask aufgelöst. Wenn setFocusBehavior()
nach Abschluss dieses Microtasks aufgerufen wird, wird ein Fehler ausgegeben.
– Wenn setFocusBehavior()
mehr als eine Sekunde nach Beginn der Erfassung aufgerufen wird, hat das keine Auswirkungen.
Das bedeutet, dass beide folgenden Snippets fehlschlagen:
// Prompt the user to share their screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
// Too late, because it follows the completion of the task
// on which the getDisplayMedia() promise resolved.
// This will throw.
setTimeout(() => {
controller.setFocusBehavior("focus-captured-surface");
});
// Prompt the user to share their screen.
const stream =
await navigator.mediaDevices.getDisplayMedia({ controller });
const start = new Date();
while (new Date() - start <= 1000) {
// Idle for ≈1s.
}
// Because too much time has elapsed, the browser will have
// already decided whether to focus.
// This fails silently.
controller.setFocusBehavior("focus-captured-surface");
In den folgenden Fällen wird auch eine Fehlermeldung ausgegeben, wenn setFocusBehavior()
aufgerufen wird:
- der Videotrack des von
getDisplayMedia()
zurückgegebenen Streams nicht „live“ ist. - nach der Auflösung des zurückgegebenen Promises von
getDisplayMedia()
, wenn der Nutzer einen Bildschirm (keinen Tab oder ein Fenster) geteilt hat.
Beispiel
Sie können mit dem bedingten Fokus experimentieren, indem Sie die Demo auf Glitch ausführen. Sehen Sie sich den Quellcode an.
Funktionserkennung
So prüfen Sie, ob CaptureController.setFocusBehavior()
unterstützt wird:
if (
"CaptureController" in window &&
"setFocusBehavior" in CaptureController.prototype
) {
// CaptureController.setFocusBehavior() is supported.
}
Feedback
Das Chrome-Team und die Webstandards-Community möchten von Ihnen wissen, welche Erfahrungen Sie mit der bedingten Fokussierung gemacht haben.
Designbeschreibung
Funktioniert der bedingte Fokus nicht wie erwartet? Oder fehlen Methoden oder Eigenschaften, die Sie für die Implementierung Ihrer Idee benötigen? Haben Sie Fragen oder Kommentare zum Sicherheitsmodell?
- Melden Sie ein Problem mit der Spezifikation im GitHub-Repository oder fügen Sie Ihre Gedanken zu einem vorhandenen Problem hinzu.
Problem bei der Implementierung?
Haben Sie einen Fehler in der Chrome-Implementierung gefunden? Oder unterscheidet sich die Implementierung von der Spezifikation?
- Melden Sie den Fehler unter https://new.crbug.com. Geben Sie dabei so viele Details wie möglich an und machen Sie eine einfache Anleitung zur Reproduktion. Glitch eignet sich gut zum Teilen von Code.
Unterstützung zeigen
Planen Sie, den bedingten Fokus zu verwenden? Ihre öffentliche Unterstützung hilft dem Chrome-Team, Funktionen zu priorisieren, und zeigt anderen Browseranbietern, wie wichtig es ist, sie zu unterstützen.
Senden Sie uns einen Tweet an @ChromiumDev und teilen Sie uns mit, wo und wie Sie es verwenden.
Nützliche Links
Danksagungen
Hero-Image von Elena Taranenko.
Vielen Dank an Rachel Andrew für die Überprüfung dieses Artikels.