Uzyskuj informacje o połączonych wyświetlaczach i oknach położenia względem tych wyświetlaczy.
Interfejs API zarządzania oknami
Interfejs Window Management API umożliwia numerowanie wyświetlaczy podłączonych do Twojego komputera i umiejscowienie okien na konkretnych ekranach.
Sugerowane zastosowania
Przykłady witryn, które mogą korzystać z tego interfejsu API:
- Edytory grafiki do wielu okien à la Gimp może umieszczać różne narzędzi do edycji w dokładnie rozmieszczonych oknach.
- Wirtualne platformy zakupowe mogą pokazywać tendencje rynkowe w wielu okresach, z których można wyświetlać trybu pełnoekranowego.
- Aplikacje do pokazu slajdów mogą wyświetlać notatki prelegenta na wewnętrznym ekranie głównym i w prezentacji na z zewnętrznego projektora.
Jak korzystać z interfejsu Window Management API
Problem
Działające od lat podejście do sterowania oknami
Window.open()
to niestety
nie wiedząc o dodatkowych ekranach. Chociaż niektóre aspekty tego interfejsu API wydają się nieco przestarzałe,
windowFeatures
DOMString
, sprawdza się on jednak na przestrzeni lat. Aby określić
position, można przekazać
współrzędne jak left
i top
(lub odpowiednio screenX
i screenY
) i przekazują wybrane
rozmiar jako
width
i height
(lub odpowiednio innerWidth
i innerHeight
). Aby na przykład otworzyć
Okno 400 × 300 w odległości 50 pikseli od lewej i 50 pikseli od góry.
może użyć:
const popup = window.open(
'https://example.com/',
'My Popup',
'left=50,top=50,width=400,height=300',
);
Informacje o bieżącym ekranie znajdziesz w
window.screen
, która
zwraca obiekt Screen
. To jest
na moim MacBooku Pro 13′′:
window.screen;
/* Output from my MacBook Pro 13″:
availHeight: 969
availLeft: 0
availTop: 25
availWidth: 1680
colorDepth: 30
height: 1050
isExtended: true
onchange: null
orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
pixelDepth: 30
width: 1680
*/
Jak większość osób pracujących w branży technologicznej musiałam dostosować się do nowej rzeczywistości w pracy i skonfigurować osobistego biura domowego. Moja wygląda tak jak na poniższym zdjęciu (jeśli chcesz, możesz zapoznać się z o mojej konfiguracji). iPad obok mojego MacBooka jest połączony z laptopem przez Sidecar, więc w razie potrzeby mogę szybko na iPadzie.
Na większym ekranie mogę umieścić wyskakujące okienko przykładowy kod powyżej na drugi ekran. Ja to robię podobny do tego:
popup.moveTo(2500, 50);
To przybliżone oszacowanie, ponieważ nie można poznać wymiarów drugiego ekranu. Informacje
od window.screen
obejmuje tylko ekran wbudowany, ale nie ekran iPada. Zgłoszone width
wbudowanego ekranu miało 1680
piks., dlatego przejście na 2500
piks. może pomóc w przesunięciu
na iPada, bo widzę, że znajduje się on po prawej stronie mojego MacBooka. Jak
Czy mogę to zrobić w ogólnym przypadku? Okazuje się, że jest lepszy sposób niż zgadywanie. Dzięki temu
Interfejs API zarządzania oknami.
Wykrywanie cech
Aby sprawdzić, czy interfejs Window Management API jest obsługiwany, użyj tego polecenia:
if ('getScreenDetails' in window) {
// The Window Management API is supported.
}
Uprawnienia window-management
Aby móc używać interfejsu Window Management API, muszę poprosić użytkownika o zgodę.
Zapytanie o uprawnienie window-management
może działać przy użyciu
Permissions API:
let granted = false;
try {
const { state } = await navigator.permissions.query({ name: 'window-management' });
granted = state === 'granted';
} catch {
// Nothing.
}
Chociaż używane są przeglądarki ze starą i nową nazwą uprawnienia, przy prośbie o uprawnienia należy używać kodu obronnego, tak jak w poniższym przykładzie.
async function getWindowManagementPermissionState() {
let state;
// The new permission name.
try {
({ state } = await navigator.permissions.query({
name: "window-management",
}));
} catch (err) {
return `${err.name}: ${err.message}`;
}
return state;
}
document.querySelector("button").addEventListener("click", async () => {
const state = await getWindowManagementPermissionState();
document.querySelector("pre").textContent = state;
});
Przeglądarka można chcę dynamicznie wyświetlać prośbę o uprawnienia przy pierwszej próbie użycia dowolnej z metod nowym API. Czytaj dalej, aby dowiedzieć się więcej.
Właściwość window.screen.isExtended
Aby sprawdzić, czy do mojego urządzenia jest podłączony więcej niż jeden ekran, otwieram
window.screen.isExtended
. Zwraca true
lub false
. W mojej konfiguracji zwraca wartość true
.
window.screen.isExtended;
// Returns `true` or `false`.
Metoda getScreenDetails()
Teraz gdy już wiem, że obecne ustawienia są dostosowywane na wiele urządzeń, mogę dowiedzieć się więcej o
drugi ekran za pomocą funkcji Window.getScreenDetails()
. Wywołanie tej funkcji spowoduje wyświetlenie prośby o zgodę, która
pyta mnie, czy strona może się otwierać i umieszczać okna na ekranie. Funkcja zwraca obietnicę
, który kończy się za pomocą obiektu ScreenDetailed
. Na moim MacBooku Pro 13 z podłączonym iPadem
w tym pole screens
z 2 obiektami ScreenDetailed
:
await window.getScreenDetails();
/* Output from my MacBook Pro 13″ with the iPad attached:
{
currentScreen: ScreenDetailed {left: 0, top: 0, isPrimary: true, isInternal: true, devicePixelRatio: 2, …}
oncurrentscreenchange: null
onscreenschange: null
screens: [{
// The MacBook Pro
availHeight: 969
availLeft: 0
availTop: 25
availWidth: 1680
colorDepth: 30
devicePixelRatio: 2
height: 1050
isExtended: true
isInternal: true
isPrimary: true
label: "Built-in Retina Display"
left: 0
onchange: null
orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
pixelDepth: 30
top: 0
width: 1680
},
{
// The iPad
availHeight: 999
availLeft: 1680
availTop: 25
availWidth: 1366
colorDepth: 24
devicePixelRatio: 2
height: 1024
isExtended: true
isInternal: false
isPrimary: false
label: "Sidecar Display (AirPlay)"
left: 1680
onchange: null
orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
pixelDepth: 24
top: 0
width: 1366
}]
}
*/
Informacje o połączonych ekranach są dostępne w tablicy screens
. Zwróć uwagę, jak wartość
left
w przypadku iPada rozpoczyna się od 1680
, czyli dokładnie width
w przypadku wbudowanego wyświetlacza. Ten
pozwala mi dokładnie określić logiczny układ ekranów (obok siebie, na górze
do siebie nawzajem itp.). Dostępne są też teraz dane dla każdego ekranu, które pokazują, czy należy on do isInternal
i określ, czy jest to isPrimary
. Wbudowany ekran
nie musi być ekranem głównym.
Pole currentScreen
jest aktywnym obiektem odpowiadającym bieżącemu obiektowi window.screen
. Obiekt
są aktualizowane w przypadku miejsc docelowych okien na różnych urządzeniach lub zmian na urządzeniach.
Wydarzenie screenschange
Obecnie brakuje tylko sposobu wykrywania zmian w konfiguracji ekranu. Nowe zdarzenie,
screenschange
robi dokładnie to samo: uruchamia się po zmianie konstelacji ekranu. (Uwaga
które „ekrany” jest liczbą mnogą w nazwie wydarzenia). Oznacza to, że zdarzenie jest uruchamiane po każdym pojawieniu się nowego ekranu lub
obecny ekran jest (fizycznie lub wirtualnie w przypadku aplikacji Sidecar) podłączony lub odłączony.
Pamiętaj, że szczegóły nowego ekranu musisz wyświetlać asynchronicznie, czyli zdarzenie screenschange
sama nie dostarcza tych danych. Aby wyszukać szczegóły ekranu, użyj aktywnego obiektu z pamięci podręcznej
Interfejs Screens
.
const screenDetails = await window.getScreenDetails();
let cachedScreensLength = screenDetails.screens.length;
screenDetails.addEventListener('screenschange', (event) => {
if (screenDetails.screens.length !== cachedScreensLength) {
console.log(
`The screen count changed from ${cachedScreensLength} to ${screenDetails.screens.length}`,
);
cachedScreensLength = screenDetails.screens.length;
}
});
Wydarzenie currentscreenchange
Jeśli interesują mnie tylko zmiany na bieżącym ekranie (czyli wartość aktywnego obiektu
currentScreen
), mogę nasłuchiwać zdarzenia currentscreenchange
.
const screenDetails = await window.getScreenDetails();
screenDetails.addEventListener('currentscreenchange', async (event) => {
const details = screenDetails.currentScreen;
console.log('The current screen has changed.', event, details);
});
Wydarzenie change
Na koniec, jeśli interesują mnie tylko zmiany na konkretnym ekranie, mogę odsłuchać
change
zdarzenie.
const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
console.log('The first screen has changed.', event, firstScreen);
});
Nowe opcje pełnego ekranu
Do tej pory można było poprosić o wyświetlanie elementów w trybie pełnoekranowym za pomocą odpowiedniej nazwy
requestFullScreen()
. Metoda przyjmuje parametr options
, w którym można przekazać
FullscreenOptions
Jak dotąd,
jego jedyną właściwością jest
navigationUI
Interfejs Window Management API dodaje nową właściwość screen
, która pozwala określić
na którym ekranie chcesz włączyć widok pełnoekranowy. Na przykład: jeśli chcesz ustawić ekran główny
pełny ekran:
try {
const primaryScreen = (await getScreenDetails()).screens.filter((screen) => screen.isPrimary)[0];
await document.body.requestFullscreen({ screen: primaryScreen });
} catch (err) {
console.error(err.name, err.message);
}
Watolina
Nie można zastosować kodu polyfill w interfejsie Window Management API, ale można podłożyć jego kształt, możesz pisać kod wyłącznie pod kątem nowego interfejsu API:
if (!('getScreenDetails' in window)) {
// Returning a one-element array with the current screen,
// noting that there might be more.
window.getScreenDetails = async () => [window.screen];
// Set to `false`, noting that this might be a lie.
window.screen.isExtended = false;
}
inne aspekty interfejsu API, takie jak różne zdarzenia zmiany ekranu i właściwość screen
.
FullscreenOptions
, nie zostanie po prostu nigdy wywołana lub zostanie zignorowana dyskretnie przez
które nie obsługują tej przeglądarki.
Prezentacja
Jeśli tak jak ja, będziesz uważnie śledzić rozwój kryptowaluty. (Właściwie to przeważnie nie, ponieważ kocham tę planetę, ale... na potrzeby tego artykułu przyjmijmy, did.) Aby śledzić posiadane kryptowaluty, stworzyłem aplikację internetową, która pozwala Obserwujemy rynki we wszystkich sytuacjach, np. w łóżku, gdzie mam przyzwoity konfiguracji na jednym ekranie.
Jeśli chodzi o kryptowaluty, na rynku panuje gwałtowny ruch w każdej chwili. Jeśli tak się stanie, mogę szybko Przejdź do mojego biurka, gdzie mam sprzęt wieloekranowy. Mogę kliknąć okno dowolnej waluty by szybko zobaczyć pełne szczegóły w widoku pełnoekranowym na drugim ekranie. Oto najnowsze zdjęcie moje zdjęcie zostało zrobione podczas ostatniej baterii YCY. Przyciągnęła mnie zupełnie niemiarodajny z rękami na twarzy.
Możesz skorzystać z umieszczonej poniżej wersji demonstracyjnej lub zobaczyć jej kod źródłowy w wersji glitch.
Bezpieczeństwo i uprawnienia
Zespół Chrome zaprojektował i wdrożył interfejs Window Management API z użyciem zasad zdefiniowanych w artykule Kontrolowanie dostępu do zaawansowanych funkcji platform internetowych, takich jak kontrola użytkownika, przejrzystość i ergonomia. Interfejs Window Management API ujawnia nowych informacji o ekranach podłączonych do urządzenia, co zwiększyło możliwości zwłaszcza tych mających wiele urządzeń, z których jeden jest stale połączony. Jako jeden aby złagodzić tę ochronę prywatności, właściwości naświetlonego ekranu są ograniczone do minimum do typowych przypadków użycia miejsc docelowych. Witryny mogą działać pod kątem wielu urządzeń dopiero po otrzymaniu uprawnień użytkownika informacjami i umieszczać okna na innych ekranach. Chromium zwraca szczegółowe etykiety ekranu, Przeglądarki mogą zwracać mniej opisowe (lub nawet puste etykiety).
Kontrola użytkowników
Użytkownik ma pełną kontrolę nad dostępem do swojej konfiguracji. Może zaakceptować lub odrzucić i cofnąć otrzymane wcześniej uprawnienia, korzystając z funkcji informacji o witrynie z przeglądarki.
Kontrola firmy
Użytkownicy Chrome Enterprise mogą kontrolować kilka aspektów interfejsu Window Management API, omówione w odpowiedniej sekcji Atomic Policy Groups (Atomowe grupy zasad) ustawieniach.
Przejrzystość
Fakt przyznania uprawnień do korzystania z interfejsu Window Management API jest widoczne w informacjach o witrynie przeglądarki, a także dla zapytań wysyłanych przez interfejs Permissions API.
Trwałość uprawnień
Przeglądarka zachowuje przyznane uprawnienia. Uprawnienia można cofnąć w witrynie przeglądarki i informacjami o nich.
Prześlij opinię
Zespół Chrome chce poznać Twoją opinię na temat korzystania z interfejsu Window Management API.
Opowiedz nam o konstrukcji interfejsu API
Czy jest coś, co nie działa w interfejsie API zgodnie z oczekiwaniami? Czy może brakuje tu metod lub właściwości potrzebne do realizacji pomysłu? Masz pytanie lub komentarz na temat zabezpieczeń model?
- Zgłoś problem ze specyfikacją w odpowiednim repozytorium GitHub lub dodaj uwagi do istniejącego Google Cloud.
Zgłoś problem z implementacją
Czy wystąpił błąd z implementacją Chrome? Czy implementacja różni się od specyfikacji?
- Zgłoś błąd na new.crbug.com. Podaj jak najwięcej szczegółów
można, wykonać proste instrukcje odtwarzania i wpisać
Blink>Screen>MultiScreen
w polu Okno Komponenty. Usługa Glitch świetnie nadaje się do szybkiego i łatwego udostępniania poprawek.
Pokaż wsparcie dla interfejsu API
Czy planujesz skorzystać z interfejsu Window Management API? Wasze publiczne wsparcie pomaga nam ulepszyć Chrome nadając priorytet funkcjom i pokazując innym dostawcom przeglądarek, jak ważne jest ich wsparcie.
- Poinformuj nas, jak zamierzasz korzystać z tego narzędzia w wątku poświęconym dysku WICG.
- Wyślij tweeta na adres @ChromiumDev, używając hashtagu
#WindowManagement
i daj nam znać, gdzie i w jaki sposób go używasz. - Poproś innych dostawców przeglądarek o wdrożenie interfejsu API.
Przydatne linki
- Wersja robocza specyfikacji
- Publiczne wyjaśnienie
- Prezentacja interfejsu Window Management API | Wersja demonstracyjna interfejsu Window Management API źródło
- Błąd śledzenia w Chromium
- Wpis na temat ChromeStatus.com
- Komponent Blink:
Blink>Screen>MultiScreen
- Ocena TAG
- Zamiar eksperymentowania
Podziękowania
Specyfikacja interfejsu Window Management API została edytowana przez Victor Costan Joshua Bell oraz Mike Wasserman Interfejs API został wdrożony przez Mike Wasserman i Adrienne Walker Ten artykuł zrecenzował(a) Joe Medley, François Beaufort, i Kayce Basques. Dziękujemy Laurze Torrent Puig za zdjęcia.