Nhận thông tin về các màn hình đã kết nối và cửa sổ vị trí tương ứng với các màn hình đó.
API Quản lý cửa sổ
API Quản lý cửa sổ cho phép bạn liệt kê các màn hình được kết nối với máy của bạn và đặt cửa sổ trên các màn hình cụ thể.
Trường hợp sử dụng được đề xuất
Ví dụ về những trang web có thể sử dụng API này bao gồm:
- Trình chỉnh sửa đồ hoạ nhiều cửa sổ à la Gimp có thể đặt nhiều công cụ chỉnh sửa vào các cửa sổ được đặt ở vị trí chính xác.
- Các bàn giao dịch ảo có thể hiển thị xu hướng thị trường trong nhiều cửa sổ mà bạn có thể xem bất kỳ cửa sổ nào ở chế độ toàn màn hình.
- Ứng dụng trình chiếu có thể hiển thị ghi chú của người thuyết trình trên màn hình chính bên trong và bản trình bày trên máy chiếu bên ngoài.
Cách sử dụng API Quản lý cửa sổ
Vấn đề
Rất tiếc, phương pháp kiểm soát cửa sổ đã được thử nghiệm theo thời gian (Window.open()
) không biết về các màn hình khác. Mặc dù một số khía cạnh của API này có vẻ hơi cũ (chẳng hạn như tham số windowFeatures
DOMString
) nhưng API này vẫn phục vụ chúng tôi rất hiệu quả trong những năm qua. Để chỉ định vị trí của cửa sổ, bạn có thể truyền các toạ độ dưới dạng left
và top
(hoặc screenX
và screenY
tương ứng) và chuyển kích thước mong muốn dưới dạng width
và height
(hoặc innerWidth
và innerHeight
tương ứng). Ví dụ: để mở cửa sổ 400×300 ở 50 pixel từ bên trái và 50 pixel ở trên cùng, đây là mã mà bạn có thể dùng:
const popup = window.open(
'https://example.com/',
'My Popup',
'left=50,top=50,width=400,height=300',
);
Bạn có thể xem thông tin về màn hình hiện tại bằng cách xem thuộc tính window.screen
. Thuộc tính này sẽ trả về đối tượng Screen
. Đây là kết quả trên MacBook Pro 13" của tôi:
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
*/
Giống như hầu hết những người làm việc trong ngành công nghệ, tôi phải tự thích nghi với thực tế công việc mới và thiết lập văn phòng tại nhà riêng của mình. của tôi trông giống như trên ảnh bên dưới (nếu quan tâm, bạn có thể đọc thông tin chi tiết đầy đủ về cách thiết lập của tôi). iPad bên cạnh MacBook của tôi được kết nối với máy tính xách tay thông qua Sidecar, vì vậy, bất cứ khi nào cần, tôi có thể nhanh chóng biến iPad thành màn hình thứ hai.
![Một chiếc ghế dài ở trường học trên hai chiếc ghế. Trên đầu ghế băng của trường là các hộp đựng giày để đỡ một chiếc máy tính xách tay và hai chiếc iPad xung quanh.](https://developer.chrome.com/static/docs/capabilities/web-apis/window-management/image/school-bench-two-chairs-8465336393f71.jpg?authuser=5&hl=vi)
Nếu muốn tận dụng màn hình lớn hơn, tôi có thể đặt cửa sổ bật lên từ mã mẫu ở trên lên màn hình thứ hai. Tôi làm như sau:
popup.moveTo(2500, 50);
Đây chỉ là phỏng đoán gần đúng vì không có cách nào để biết kích thước của màn hình thứ hai. Thông tin từ window.screen
chỉ bao gồm màn hình tích hợp chứ không bao gồm màn hình iPad. width
được báo cáo của màn hình tích hợp là 1680
pixel, vì vậy, việc di chuyển sang 2500
pixel có thể làm việc để chuyển cửa sổ sang iPad, vì tôi tình cờ biết rằng cửa sổ này nằm ở bên phải MacBook của tôi. Trong trường hợp chung đó, tôi có thể làm như thế nào? Hoá ra, vẫn có cách tốt hơn là đoán. Đó là API Quản lý cửa sổ.
Phát hiện tính năng
Để kiểm tra xem Window Management API có được hỗ trợ hay không, hãy sử dụng:
if ('getScreenDetails' in window) {
// The Window Management API is supported.
}
Quyền window-management
Trước khi có thể sử dụng API Quản lý cửa sổ, tôi phải yêu cầu người dùng cấp quyền làm như vậy.
Bạn có thể truy vấn quyền window-management
bằng
API Quyền như sau:
let granted = false;
try {
const { state } = await navigator.permissions.query({ name: 'window-management' });
granted = state === 'granted';
} catch {
// Nothing.
}
Mặc dù các trình duyệt có tên quyền cũ và mới đang được sử dụng, hãy nhớ sử dụng mã phòng vệ khi yêu cầu quyền, như trong ví dụ dưới đây.
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;
});
Trình duyệt có thể chọn tự động hiển thị lời nhắc cấp quyền trong lần đầu tiên sử dụng bất kỳ phương thức nào của API mới. Hãy đọc tiếp để tìm hiểu thêm.
Thuộc tính window.screen.isExtended
Để tìm hiểu xem có nhiều màn hình được kết nối với thiết bị của tôi hay không, tôi truy cập vào thuộc tính window.screen.isExtended
. Phương thức này trả về true
hoặc false
. Theo cách thiết lập của tôi, phương thức này trả về true
.
window.screen.isExtended;
// Returns `true` or `false`.
Phương thức getScreenDetails()
Bây giờ, tôi đã biết rằng chế độ thiết lập hiện tại là nhiều màn hình, tôi có thể biết thêm thông tin về màn hình thứ hai bằng cách sử dụng Window.getScreenDetails()
. Khi gọi hàm này, một lời nhắc cấp quyền sẽ hỏi tôi xem trang web có thể mở và đặt các cửa sổ trên màn hình của tôi hay không. Hàm này trả về một lời hứa sẽ phân giải bằng đối tượng ScreenDetailed
. Trên MacBook Pro 13 của tôi có một iPad đã kết nối, trường này bao gồm một trường screens
với 2 đối tượng 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
}]
}
*/
Thông tin về các màn hình đã kết nối có trong mảng screens
. Hãy lưu ý cách giá trị của left
cho iPad bắt đầu từ 1680
, chính xác là width
của màn hình tích hợp. Việc này cho phép tôi xác định chính xác cách sắp xếp các màn hình một cách hợp lý (cạnh nhau, chồng lên nhau, v.v.). Hiện cũng có dữ liệu cho mỗi màn hình để cho biết đó có phải là màn hình isInternal
hay không và đó có phải là màn hình isPrimary
hay không. Xin lưu ý rằng màn hình tích hợp không nhất thiết là màn hình chính.
Trường currentScreen
là một đối tượng trực tiếp tương ứng với window.screen
hiện tại. Đối tượng được cập nhật khi có các vị trí cửa sổ trên nhiều màn hình hoặc các thay đổi về thiết bị.
Sự kiện screenschange
Điều duy nhất còn thiếu bây giờ là cách phát hiện thời điểm thiết lập màn hình của tôi thay đổi. Một sự kiện mới screenschange
sẽ hoạt động chính xác như vậy: sự kiện này sẽ kích hoạt bất cứ khi nào chòm sao trên màn hình được sửa đổi. (Xin lưu ý rằng "màn hình" là số nhiều trong tên sự kiện.) Điều này có nghĩa là sự kiện sẽ kích hoạt bất cứ khi nào một màn hình mới hoặc màn hình hiện có được cắm hoặc rút phích cắm (về mặt thực tế hoặc ảo trong trường hợp Sidecar).
Xin lưu ý rằng bạn cần tra cứu không đồng bộ thông tin chi tiết về màn hình mới, sự kiện screenschange
không cung cấp dữ liệu này. Để tra cứu thông tin chi tiết trên màn hình, hãy sử dụng đối tượng trực tiếp qua giao diện Screens
đã lưu vào bộ nhớ đệm.
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;
}
});
Sự kiện currentscreenchange
Nếu chỉ quan tâm đến các thay đổi đối với màn hình hiện tại (tức là giá trị của đối tượng trực tiếp currentScreen
), tôi có thể theo dõi sự kiện currentscreenchange
.
const screenDetails = await window.getScreenDetails();
screenDetails.addEventListener('currentscreenchange', async (event) => {
const details = screenDetails.currentScreen;
console.log('The current screen has changed.', event, details);
});
Sự kiện change
Cuối cùng, nếu chỉ quan tâm đến các thay đổi đối với màn hình cụ thể, tôi có thể theo dõi sự kiện change
của màn hình đó.
const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
console.log('The first screen has changed.', event, firstScreen);
});
Tuỳ chọn toàn màn hình mới
Cho đến nay, bạn có thể yêu cầu hiển thị các phần tử ở chế độ toàn màn hình thông qua phương thức requestFullScreen()
được đặt tên thích hợp. Phương thức này sẽ lấy tham số options
để bạn có thể truyền FullscreenOptions
. Cho đến nay, thuộc tính duy nhất của API này là navigationUI
.
API Quản lý cửa sổ thêm một thuộc tính screen
mới cho phép bạn xác định màn hình nào sẽ bắt đầu ở chế độ xem toàn màn hình. Ví dụ: nếu bạn muốn đặt màn hình chính ở chế độ toàn màn hình:
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);
}
Vải polyfill
Bạn không thể chèn lấp API Quản lý cửa sổ, nhưng bạn có thể chỉnh sửa hình dạng của API này để có thể viết mã độc quyền dựa trên API mới:
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;
}
Các khía cạnh khác của API, tức là các sự kiện thay đổi màn hình khác nhau và thuộc tính screen
của FullscreenOptions
, sẽ không bao giờ kích hoạt hoặc sẽ tự động bị các trình duyệt không hỗ trợ bỏ qua.
Bản minh hoạ
Nếu bạn là một nhà sáng tạo giống như tôi, bạn sẽ theo dõi chặt chẽ sự phát triển của nhiều loại tiền mã hoá. (Trong thực tế, tôi rất không yêu thích hành tinh này, nhưng trong bài viết này, hãy giả định như tôi đã yêu cầu hành tinh này.) Để theo dõi tiền mã hoá mà tôi sở hữu, tôi đã phát triển một ứng dụng web cho phép tôi xem thị trường trong mọi tình huống cuộc sống, chẳng hạn như ngay trên giường, nơi tôi thiết lập vừa phải trên một màn hình đơn.
![Màn hình TV khổng lồ ở cuối giường, có đôi chân của tác giả xuất hiện. Trên màn hình là một bàn giao dịch tiền mã hoá giả.](https://developer.chrome.com/static/docs/capabilities/web-apis/window-management/image/massive-tv-screen-the-en-c57bfb0e325ff.jpg?authuser=5&hl=vi)
Liên quan đến tiền mã hoá, thị trường có thể trở nên sôi động bất cứ lúc nào. Nếu điều này xảy ra, tôi có thể nhanh chóng chuyển sang bàn làm việc của mình, nơi tôi có chế độ thiết lập nhiều màn hình. Tôi có thể nhấp vào cửa sổ của đơn vị tiền tệ bất kỳ và xem nhanh toàn bộ thông tin chi tiết ở chế độ xem toàn màn hình trên màn hình đối diện. Dưới đây là ảnh chụp gần đây của tôi trong lần tắm máu YCY vừa qua. Thông tin này khiến tôi hoàn toàn mất cảnh giác và để tay lên mặt.
![Tác giả với hai tay che mặt hoảng loạn, đang nhìn vào bàn giao dịch tiền mã hoá giả.](https://developer.chrome.com/static/docs/capabilities/web-apis/window-management/image/the-author-his-hands-hi-0d430520b074a.jpg?authuser=5&hl=vi)
Bạn có thể phát bằng bản minh hoạ được nhúng bên dưới hoặc xem mã nguồn của bản minh hoạ đó trên sự cố.
Tính bảo mật và quyền
Nhóm Chrome đã thiết kế và triển khai API Quản lý cửa sổ theo các nguyên tắc cốt lõi được xác định trong Kiểm soát quyền truy cập vào các tính năng nền tảng web mạnh mẽ, bao gồm quyền kiểm soát của người dùng, độ trong suốt và hiệu quả. API Quản lý cửa sổ hiển thị thông tin mới về các màn hình được kết nối với một thiết bị, giúp tăng giao diện tạo vân tay số cho người dùng, đặc biệt là những người có nhiều màn hình được kết nối liên tục với thiết bị của họ. Để giảm thiểu mối lo ngại về quyền riêng tư này, các thuộc tính màn hình hiển thị được giới hạn ở mức tối thiểu cần thiết cho các trường hợp sử dụng vị trí phổ biến. Các trang web cần có quyền của người dùng để nhận thông tin về nhiều màn hình và đặt cửa sổ trên các màn hình khác. Mặc dù Chromium trả về nhãn màn hình chi tiết, nhưng các trình duyệt vẫn có thể trả về ít nhãn mô tả hơn (hoặc thậm chí là nhãn trống).
Quyền kiểm soát của người dùng
Người dùng có toàn quyền kiểm soát việc hiển thị quảng cáo trong chế độ thiết lập của họ. Họ có thể chấp nhận hoặc từ chối lời nhắc cấp quyền và thu hồi quyền đã cấp trước đó thông qua tính năng thông tin trang web trong trình duyệt.
Quyền kiểm soát trong doanh nghiệp
Người dùng Chrome Enterprise có thể kiểm soát một số khía cạnh của API Quản lý cửa sổ như đã nêu trong phần có liên quan của chế độ cài đặt Nhóm chính sách nguyên tử.
Sự minh bạch
Trên thực tế, việc quyền sử dụng API Quản lý cửa sổ đã được cấp hay chưa sẽ xuất hiện trong thông tin trang web của trình duyệt và cũng có thể truy vấn được qua API Quyền.
Khả năng lưu trữ cố định quyền
Trình duyệt vẫn duy trì việc cấp quyền. Quyền này có thể bị thu hồi thông qua thông tin trang web của trình duyệt.
Ý kiến phản hồi
Nhóm Chrome muốn biết về trải nghiệm của bạn với API Quản lý cửa sổ.
Cho chúng tôi biết về thiết kế của API
Có điều gì về API không hoạt động như bạn mong đợi không? Hay có thiếu phương thức hoặc thuộc tính nào mà bạn cần triển khai không? Bạn có thắc mắc hoặc nhận xét về mô hình bảo mật?
- Gửi vấn đề về thông số kỹ thuật trên kho lưu trữ GitHub tương ứng hoặc thêm ý kiến vào vấn đề hiện có.
Báo cáo sự cố với quá trình triển khai
Bạn có phát hiện thấy lỗi khi triển khai Chrome không? Hay cách triển khai có khác với quy cách không?
- Báo cáo lỗi tại new.crbug.com. Hãy nhớ cung cấp nhiều thông tin chi tiết nhất có thể, hướng dẫn đơn giản để tái tạo rồi nhập
Blink>Screen>MultiScreen
vào hộp Thành phần. Sự cố rất hữu ích trong việc chia sẻ các bản sao nhanh và dễ dàng.
Hỗ trợ API
Bạn có định sử dụng API Quản lý cửa sổ không? Sự hỗ trợ công khai của bạn giúp nhóm Chrome ưu tiên các tính năng và cho các nhà cung cấp trình duyệt khác biết tầm quan trọng của việc hỗ trợ các tính năng đó.
- Chia sẻ cách bạn dự định sử dụng tính năng này trên chuỗi bài đăng WICG Discourse.
- Hãy gửi một dòng tweet đến @ChromiumDev bằng hashtag
#WindowManagement
rồi cho chúng tôi biết vị trí và cách bạn đang sử dụng bài đăng này. - Hãy yêu cầu các nhà cung cấp trình duyệt khác triển khai API này.
Các đường liên kết hữu ích
- Bản nháp quy cách
- Nội dung giải thích công khai
- Bản minh hoạ API Quản lý cửa sổ | Nguồn minh hoạ API Quản lý cửa sổ
- Lỗi theo dõi Chromium
- Mục ChromeStatus.com
- Thành phần nhấp nháy:
Blink>Screen>MultiScreen
- Xem xét TAG
- Ý định thử nghiệm
Xác nhận
Thông số kỹ thuật Window Management API được chỉnh sửa bởi Victor Costan, Joshua Bell và Mike Wasserman. API này do Mike Wasserman và Adrienne Walker triển khai. Bài viết này đã được Joe Medley, François Beaufort và Kayce Basques đánh giá. Cảm ơn Laura Torrent Puig đã chụp những bức ảnh này.