รับข้อมูลเกี่ยวกับจอแสดงผลที่เชื่อมต่อและจัดตำแหน่งหน้าต่างตามจอแสดงผลเหล่านั้น
Window Management API
Window Management API ช่วยให้คุณแจกแจงจอแสดงผลที่เชื่อมต่อกับเครื่องและวางหน้าต่างบนหน้าจอที่ต้องการได้
กรณีการใช้งานที่แนะนํา
ตัวอย่างเว็บไซต์ที่อาจใช้ API นี้ ได้แก่
- โปรแกรมแก้ไขกราฟิกแบบหลายหน้าต่างอย่าง Gimp สามารถวางเครื่องมือแก้ไขต่างๆ ในหน้าต่างที่วางตำแหน่งได้อย่างแม่นยำ
- แผนกซื้อขายเสมือนจริงสามารถแสดงแนวโน้มตลาดในหลายหน้าต่าง ซึ่งหน้าต่างแต่ละหน้าต่างจะดูได้ในโหมดเต็มหน้าจอ
- แอปสไลด์โชว์จะแสดงโน้ตของผู้บรรยายบนหน้าจอหลักภายในและงานนำเสนอบนโปรเจ็กเตอร์ภายนอกได้
วิธีใช้ Window Management API
ปัญหา
น่าเสียดายที่Window.open()
ซึ่งเป็นแนวทางที่ผ่านการทดสอบมาอย่างยาวนานในการควบคุมหน้าต่าง ไม่ทราบว่ามีหน้าจอเพิ่มเติม แม้ว่าบางแง่มุมของ API นี้จะดูล้าสมัยไปหน่อย เช่น พารามิเตอร์ windowFeatures
DOMString
แต่เราก็ใช้ API นี้มาอย่างยาวนาน หากต้องการระบุตําแหน่งของหน้าต่าง ให้ส่งพิกัดเป็น left
และ top
(หรือ screenX
และ screenY
ตามลําดับ) และส่งขนาดที่ต้องการเป็น width
และ height
(หรือ innerWidth
และ innerHeight
ตามลําดับ) เช่น หากต้องการเปิดหน้าต่างขนาด 400×300 ที่ 50 พิกเซลจากด้านซ้ายและ 50 พิกเซลจากด้านบน คุณจะสามารถใช้โค้ดต่อไปนี้
const popup = window.open(
'https://example.com/',
'My Popup',
'left=50,top=50,width=400,height=300',
);
คุณสามารถดูข้อมูลเกี่ยวกับหน้าจอปัจจุบันได้โดยดูที่พร็อพเพอร์ตี้ window.screen
ซึ่งจะแสดงผลออบเจ็กต์ Screen
นี่คือเอาต์พุตบน MacBook 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
*/
เช่นเดียวกับคนส่วนใหญ่ที่ทำงานด้านเทคโนโลยี ฉันต้องปรับตัวให้เข้ากับสภาพการทำงานแบบใหม่และตั้งค่าสำนักงานในบ้านส่วนตัว ของฉันมีลักษณะดังรูปภาพด้านล่าง (หากสนใจ คุณสามารถอ่านรายละเอียดทั้งหมดเกี่ยวกับการตั้งค่าของฉัน) iPad ข้าง MacBook เชื่อมต่อกับแล็ปท็อปผ่าน Sidecar ดังนั้นฉันจึงเปลี่ยน iPad เป็นหน้าจอที่ 2 ได้อย่างรวดเร็วเมื่อใดก็ตามที่ต้องการ
หากต้องการใช้ประโยชน์จากหน้าจอที่ใหญ่ขึ้น ฉันสามารถวางป๊อปอัปจากตัวอย่างโค้ดด้านบนไปยังหน้าจอที่ 2 ได้ ฉันทำดังนี้
popup.moveTo(2500, 50);
นี่เป็นค่าประมาณคร่าวๆ เนื่องจากเราไม่ทราบขนาดของหน้าจอที่ 2 ข้อมูลจาก window.screen
จะครอบคลุมเฉพาะหน้าจอในตัว แต่ไม่ครอบคลุมหน้าจอ iPad width
ที่รายงานของหน้าจอในตัวคือ 1680
พิกเซล ดังนั้นการเปลี่ยนเป็น 2500
พิกเซลอาจช่วยในการเลื่อนหน้าต่างไปยัง iPad ได้ เนื่องจากฉันทราบมาว่า iPad อยู่ทางด้านขวาของ MacBook ฉันจะทำอย่างไรในกรณีทั่วไป แต่คุณก็ใช้วิธีอื่นที่ดีกว่าการคาดเดาได้ ซึ่งก็คือ Window Management API
การตรวจหาองค์ประกอบ
หากต้องการตรวจสอบว่าระบบรองรับ Window Management API หรือไม่ ให้ใช้รายการต่อไปนี้
if ('getScreenDetails' in window) {
// The Window Management API is supported.
}
สิทธิ์ window-management
ก่อนที่จะใช้ Window Management API ได้ เราต้องขอสิทธิ์จากผู้ใช้
คุณสามารถค้นหาสิทธิ์ window-management
ได้ด้วย Permissions API ดังนี้
let granted = false;
try {
const { state } = await navigator.permissions.query({ name: 'window-management' });
granted = state === 'granted';
} catch {
// Nothing.
}
ขณะที่มีการใช้เบราว์เซอร์ที่มีชื่อสิทธิ์แบบเก่าและแบบใหม่ ให้ใช้โค้ดป้องกันเมื่อขอสิทธิ์ ดังตัวอย่างด้านล่าง
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;
});
เบราว์เซอร์สามารถเลือกที่จะแสดงข้อความแจ้งสิทธิ์แบบไดนามิกเมื่อพยายามใช้เมธอดใดก็ได้ของ API ใหม่เป็นครั้งแรก อ่านต่อเพื่อดูข้อมูลเพิ่มเติม
พร็อพเพอร์ตี้ window.screen.isExtended
หากต้องการดูว่ามีหน้าจอมากกว่า 1 จอเชื่อมต่อกับอุปกรณ์หรือไม่ ฉันจะเข้าถึงพร็อพเพอร์ตี้ window.screen.isExtended
ผลการค้นหาจะแสดง true
หรือ false
การตั้งค่าของฉันแสดงผลเป็น true
window.screen.isExtended;
// Returns `true` or `false`.
getScreenDetails()
เมื่อทราบว่าการตั้งค่าปัจจุบันเป็นแบบหลายหน้าจอแล้ว ฉันจึงขอข้อมูลเพิ่มเติมเกี่ยวกับหน้าจอที่ 2 ได้โดยใช้ Window.getScreenDetails()
การเรียกใช้ฟังก์ชันนี้จะแสดงข้อความแจ้งสิทธิ์
ที่ถามฉันว่าเว็บไซต์สามารถเปิดและวางหน้าต่างบนหน้าจอของฉันได้หรือไม่ ฟังก์ชันดังกล่าวจะแสดงผลสัญญาที่แก้ไขด้วยออบเจ็กต์ ScreenDetailed
ใน MacBook Pro 13 ที่เชื่อมต่อกับ iPad ของฉัน
มีฟิลด์ screens
ที่มีออบเจ็กต์ ScreenDetailed
2 รายการ ดังนี้
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
}]
}
*/
ข้อมูลเกี่ยวกับหน้าจอที่เชื่อมต่อจะอยู่ในอาร์เรย์ screens
โปรดสังเกตว่าค่าของ left
สำหรับ iPad เริ่มต้นที่ 1680
ซึ่งตรงกับ width
ของจอแสดงผลในตัว วิธีนี้ช่วยให้ฉันกำหนดการจัดเรียงหน้าจออย่างมีเหตุผลได้ (วางข้างกัน วางซ้อนกัน ฯลฯ) นอกจากนี้ ยังมีข้อมูลสำหรับแต่ละหน้าจอเพื่อระบุว่าเป็นหน้าจอ isInternal
หรือไม่ และเป็นหน้าจอ isPrimary
หรือไม่ โปรดทราบว่าหน้าจอในตัวไม่จำเป็นต้องเป็นหน้าจอหลัก
ฟิลด์ currentScreen
คือออบเจ็กต์แบบเรียลไทม์ที่สอดคล้องกับ window.screen
ปัจจุบัน ระบบจะอัปเดตออบเจ็กต์ในตำแหน่งหน้าต่างแบบข้ามหน้าจอหรือมีการเปลี่ยนแปลงอุปกรณ์
กิจกรรม screenschange
สิ่งเดียวที่ขาดหายไปตอนนี้คือวิธีตรวจหาเมื่อการตั้งค่าหน้าจอของฉันเปลี่ยนแปลง เหตุการณ์ใหม่ screenschange
จะทําเช่นนั้นทุกประการ โดยจะทริกเกอร์เมื่อใดก็ตามที่มีการแก้ไขกลุ่มดาวของหน้าจอ (โปรดสังเกตว่า "screens" เป็นพหูพจน์ในชื่อเหตุการณ์) ซึ่งหมายความว่าเหตุการณ์จะเริ่มต้นทุกครั้งที่เสียบหรือถอดปลั๊กหน้าจอใหม่หรือหน้าจอที่มีอยู่ (จริงหรือเสมือนในกรณีของ Sidecar)
โปรดทราบว่าคุณต้องค้นหารายละเอียดหน้าจอใหม่แบบไม่พร้อมกัน เนื่องจากเหตุการณ์ screenschange
ไม่ได้ให้ข้อมูลนี้ หากต้องการค้นหารายละเอียดหน้าจอ ให้ใช้ออบเจ็กต์แบบเรียลไทม์จากอินเทอร์เฟซ 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;
}
});
เหตุการณ์ currentscreenchange
หากสนใจเฉพาะการเปลี่ยนแปลงในหน้าจอปัจจุบัน (นั่นคือ ค่าของออบเจ็กต์แบบเรียลไทม์ currentScreen
) ฉันจะฟังเหตุการณ์ currentscreenchange
ได้
const screenDetails = await window.getScreenDetails();
screenDetails.addEventListener('currentscreenchange', async (event) => {
const details = screenDetails.currentScreen;
console.log('The current screen has changed.', event, details);
});
กิจกรรม change
สุดท้ายนี้ หากสนใจเฉพาะการเปลี่ยนแปลงในหน้าจอที่เฉพาะเจาะจง ฉันก็สามารถฟังเหตุการณ์ change
ของหน้าจอนั้นได้
const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
console.log('The first screen has changed.', event, firstScreen);
});
ตัวเลือกแบบเต็มหน้าจอใหม่
ก่อนหน้านี้ คุณสามารถขอให้องค์ประกอบแสดงในโหมดเต็มหน้าจอผ่านเมธอดที่มีชื่อเหมาะเจาะอย่าง requestFullScreen()
เมธอดนี้ใช้พารามิเตอร์ options
ซึ่งคุณสามารถส่งผ่าน FullscreenOptions
ได้ จนถึงตอนนี้ พร็อพเพอร์ตี้เดียวของแบรนด์นี้คือ navigationUI
Window Management API จะเพิ่มพร็อพเพอร์ตี้ screen
ใหม่ที่ช่วยให้คุณกำหนดหน้าจอที่จะเริ่มมุมมองแบบเต็มหน้าจอได้ เช่น หากต้องการทำให้หน้าจอหลักเป็นแบบเต็มหน้าจอ ให้ทำดังนี้
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);
}
โพลีฟิลล์
คุณไม่สามารถโพลีฟิล Window Management API ได้ แต่สามารถปรับแต่งรูปแบบเพื่อให้เขียนโค้ดกับ 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;
}
ส่วนอื่นๆ ของ API เช่น เหตุการณ์การเปลี่ยนแปลงหน้าจอต่างๆ และพร็อพเพอร์ตี้ screen
ของ FullscreenOptions
จะไม่ทํางานหรือถูกละเว้นโดยเบราว์เซอร์ที่ไม่รองรับ
สาธิต
หากคุณเป็นเหมือนเรา คุณคงคอยติดตามการพัฒนาของคริปโตเคอเรนซีต่างๆ อย่างใกล้ชิด (จริงๆ แล้วฉันไม่ชอบเลยเพราะฉันรักโลกใบนี้ แต่เพื่อประโยชน์ของบทความนี้ โปรดคิดว่าฉันชอบ) เราได้พัฒนาเว็บแอปที่ช่วยติดตามคริปโตเคอเรนซีที่ฉันเป็นเจ้าของ ซึ่งช่วยให้ฉันติดตามตลาดได้ในทุกสถานการณ์ เช่น นั่งอยู่บนเตียงอย่างสบายๆ โดยใช้การตั้งค่าหน้าจอเดียวที่ยอดเยี่ยม
นี่เป็นเรื่องคริปโต ตลาดเริ่มมีความวุ่นวายได้ตลอดเวลา หากเกิดกรณีเช่นนี้ ฉันสามารถไปที่โต๊ะทำงาน ที่มีการตั้งค่าหลายหน้าจอได้อย่างรวดเร็ว ฉันคลิกหน้าต่างสกุลเงินใดก็ได้และดูรายละเอียดทั้งหมดได้อย่างรวดเร็วในมุมมองแบบเต็มหน้าจอบนหน้าจออีกฝั่ง ด้านล่างนี้คือรูปภาพล่าสุดของฉันที่ถ่ายในช่วงYCY bloodbath ครั้งล่าสุด เราเอามือปิดหน้าอยู่เลย
คุณอาจเล่นกับการสาธิตที่ฝังอยู่ด้านล่าง หรือดูซอร์สโค้ดในข้อบกพร่องก็ได้
ความปลอดภัยและสิทธิ์
ทีม Chrome ได้ออกแบบและติดตั้งใช้งาน Window Management API โดยใช้หลักการหลักที่ระบุไว้ในการควบคุมการเข้าถึงฟีเจอร์ที่มีประสิทธิภาพของแพลตฟอร์มเว็บ ซึ่งรวมถึงการควบคุมของผู้ใช้ ความโปร่งใส และลักษณะการใช้งานที่สะดวกสบาย Window Management API แสดงข้อมูลใหม่เกี่ยวกับหน้าจอที่เชื่อมต่อกับอุปกรณ์ ซึ่งจะเพิ่มพื้นผิวการเก็บลายนิ้วมือของผู้ใช้ โดยเฉพาะผู้ใช้ที่มีหลายหน้าจอเชื่อมต่อกับอุปกรณ์อย่างต่อเนื่อง หนึ่งในวิธีบรรเทาข้อกังวลด้านความเป็นส่วนตัวนี้คือการจำกัดพร็อพเพอร์ตี้หน้าจอที่แสดงไว้ให้น้อยที่สุดเท่าที่จำเป็นสำหรับกรณีการใช้งานตำแหน่งโฆษณาทั่วไป เว็บไซต์ต้องได้รับสิทธิ์จากผู้ใช้จึงจะรับข้อมูลหน้าจอหลายหน้าจอและวางหน้าต่างในหน้าจออื่นๆ ได้ แม้ว่า Chromium จะแสดงป้ายกำกับหน้าจอโดยละเอียด แต่เบราว์เซอร์จะแสดงป้ายกำกับที่สื่อความหมายน้อยลง (หรือแม้แต่ป้ายกำกับว่าง) ก็ได้
การควบคุมของผู้ใช้
ผู้ใช้จะควบคุมการแสดงการตั้งค่าของตนเองได้อย่างเต็มที่ โดยจะยอมรับหรือปฏิเสธข้อความแจ้งเกี่ยวกับสิทธิ์ และเพิกถอนสิทธิ์ที่ให้ไว้ก่อนหน้านี้ผ่านฟีเจอร์ข้อมูลเว็บไซต์ในเบราว์เซอร์ได้
การควบคุมองค์กร
ผู้ใช้ Chrome Enterprise สามารถควบคุมหลายแง่มุมของ Window Management API ตามที่ระบุไว้ในส่วนที่เกี่ยวข้องของการตั้งค่า Atomic Policy Groups
ความโปร่งใส
ข้อมูลว่ามีการอนุญาตให้ใช้ Window Management API หรือไม่จะแสดงในข้อมูลเว็บไซต์ของเบราว์เซอร์และสามารถค้นหาผ่าน Permissions API ได้ด้วย
การเก็บรักษาสิทธิ์
เบราว์เซอร์จะยังคงให้สิทธิ์อยู่ คุณเพิกถอนสิทธิ์ผ่านข้อมูลเว็บไซต์ของเบราว์เซอร์ได้
ความคิดเห็น
ทีม Chrome อยากทราบความคิดเห็นของคุณเกี่ยวกับ Window Management API
บอกเราเกี่ยวกับการออกแบบ API
มีสิ่งใดเกี่ยวกับ API ที่ไม่ทำงานตามที่คาดไว้ไหม หรือมีเมธอดหรือพร็อพเพอร์ตี้ที่ขาดหายไปซึ่งคุณต้องนำไปใช้กับแนวคิดของคุณ หากมีคำถามหรือความคิดเห็นเกี่ยวกับรูปแบบการรักษาความปลอดภัย
- แจ้งปัญหาเกี่ยวกับข้อกำหนดใน GitHub repo ที่เกี่ยวข้อง หรือแสดงความคิดเห็นในปัญหาที่มีอยู่
รายงานปัญหาเกี่ยวกับการติดตั้งใช้งาน
หากพบข้อบกพร่องในการใช้งาน Chrome หรือการติดตั้งใช้งานแตกต่างจากข้อมูลจำเพาะหรือไม่
- รายงานข้อบกพร่องที่ new.crbug.com โปรดระบุรายละเอียดให้มากที่สุด วิธีการง่ายๆ ในการจำลองข้อบกพร่อง และป้อน
Blink>Screen>MultiScreen
ในช่องคอมโพเนนต์ Glitch เหมาะอย่างยิ่งสำหรับการแชร์การจำลองข้อบกพร่องที่รวดเร็วและง่ายดาย
แสดงการสนับสนุน API
คุณวางแผนที่จะใช้ Window Management API ใช่ไหม การสนับสนุนแบบสาธารณะของคุณจะช่วยให้ทีม Chrome จัดลำดับความสำคัญของฟีเจอร์ต่างๆ และแสดงให้เห็นว่าการสนับสนุนฟีเจอร์เหล่านี้สำคัญกับผู้ให้บริการเบราว์เซอร์รายอื่นๆ เพียงใด
- แชร์ว่าคุณวางแผนจะใช้ WICG อย่างไรในชุดข้อความ Discourse ของ WICG
- ส่งทวีตถึง @ChromiumDev โดยใช้แฮชแท็ก
#WindowManagement
และบอกเราว่าคุณกำลังใช้ฟีเจอร์นี้ที่ไหนและอย่างไร - สอบถามผู้ให้บริการเบราว์เซอร์รายอื่นๆ เพื่อใช้ API นี้
ลิงก์ที่มีประโยชน์
- ฉบับร่างข้อกำหนด
- คำอธิบายแบบสาธารณะ
- การสาธิต Window Management API | แหล่งที่มาการสาธิต Window Management API
- ข้อบกพร่องในการติดตาม Chromium
- รายการ ChromeStatus.com
- คอมโพเนนต์ Blink:
Blink>Screen>MultiScreen
- ตรวจสอบแท็ก
- ความตั้งใจที่จะทดสอบ
ขอขอบคุณ
ข้อมูลจำเพาะของ Window Management API ได้รับการแก้ไขโดย Victor Costan, Joshua Bell และ Mike Wasserman API นี้ติดตั้งใช้งานโดย Mike Wasserman และ Adrienne Walker บทความนี้ได้รับการตรวจสอบโดย Joe Medley, François Beaufort และ Kayce Basques ขอขอบคุณ Laura Torrent Puig สำหรับรูปภาพ