Screen Capture API ช่วยให้ผู้ใช้เลือกแท็บ หน้าต่าง หรือหน้าจอที่จะจับภาพเป็นสตรีมสื่อได้ จากนั้นจะสามารถบันทึกหรือแชร์สตรีมนี้กับผู้อื่นผ่านเครือข่ายได้ เอกสารนี้อธิบายโฟกัสแบบมีเงื่อนไข ซึ่งเป็นกลไกสำหรับเว็บแอปในการควบคุมว่าระบบจะโฟกัสแท็บหรือหน้าต่างที่จับภาพไว้เมื่อการจับภาพเริ่มต้นขึ้นหรือไม่ หรือหน้าเว็บที่จับภาพไว้จะยังคงโฟกัสอยู่หรือไม่
การสนับสนุนเบราว์เซอร์
โฟกัสแบบมีเงื่อนไขพร้อมใช้งานใน Chrome 109
ข้อมูลเบื้องต้น
เมื่อเว็บแอปเริ่มจับภาพแท็บหรือหน้าต่าง เบราว์เซอร์จะต้องตัดสินใจว่าควรนำแพลตฟอร์มที่จับภาพมาแสดงที่เบื้องหน้า หรือให้โฟกัสที่หน้าเว็บที่จับภาพอยู่ต่อไป คำตอบจะขึ้นอยู่กับเหตุผลในการเรียกใช้ getDisplayMedia()
และขึ้นอยู่กับแพลตฟอร์มที่ผู้ใช้เลือก
ลองพิจารณาเว็บแอปการประชุมทางวิดีโอสมมติ เว็บแอปการประชุมทางวิดีโอจะเข้าใจสิ่งที่ผู้ใช้เลือกแชร์ได้ด้วยการอ่าน track.getSettings().displaySurface
และอาจตรวจสอบแฮนเดิลการจับภาพ จากนั้นให้ทำดังนี้
- หากควบคุมแท็บหรือหน้าต่างที่จับภาพไว้จากระยะไกลได้ ให้โฟกัสที่วิดีโอคอนเฟอเรนซ์ไว้
- หรือโฟกัสแท็บหรือหน้าต่างที่จับภาพไว้
ในตัวอย่างข้างต้น เว็บแอปการประชุมทางวิดีโอจะยังคงโฟกัสหากแชร์ชุดสไลด์ เพื่อให้ผู้ใช้เลื่อนดูสไลด์จากระยะไกลได้ แต่หากผู้ใช้เลือกแชร์เครื่องมือแก้ไขข้อความ เว็บแอปการประชุมทางวิดีโอจะเปลี่ยนโฟกัสไปยังแท็บหรือหน้าต่างที่บันทึกไว้ทันที
การใช้ Conditional Focus API
สร้างอินสแตนซ์ CaptureController
แล้วส่งไปยัง getDisplayMedia()
การเรียก setFocusBehavior()
ทันทีหลังจากที่ Promise ที่ getDiplayMedia()
แสดงผลจะแก้ไข จะช่วยให้คุณควบคุมได้ว่าจะให้โฟกัสแท็บหรือหน้าต่างที่จับภาพไว้หรือไม่ ซึ่งทำได้ก็ต่อเมื่อผู้ใช้แชร์แท็บหรือหน้าต่างเท่านั้น
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");
}
เมื่อตัดสินใจว่าจะโฟกัสหรือไม่ คุณอาจพิจารณาแฮนเดิลการจับภาพ
// 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");
}
คุณยังเลือกได้ว่าจะโฟกัสก่อนโทร getDisplayMedia()
หรือไม่
// 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 });
คุณสามารถเรียก setFocusBehavior()
กี่ครั้งก็ได้ก่อนที่ Promise จะได้รับการแก้ไข หรือเรียกได้สูงสุด 1 ครั้งทันทีหลังจากที่ Promise ได้รับการแก้ไข การเรียกใช้สุดท้ายจะลบล้างการเรียกใช้ก่อนหน้าทั้งหมด
แม่นยำมากขึ้น
- สัญญาที่ getDisplayMedia()
ส่งคืนมาได้รับการแก้ไขใน Microtask การเรียก setFocusBehavior()
หลังจากไมโครแทสก์นั้นเสร็จสมบูรณ์จะทำให้เกิดข้อผิดพลาด
- การเรียก setFocusBehavior()
นานกว่า 1 วินาทีหลังจากการจับภาพเริ่มต้นจะใช้งานไม่ได้
กล่าวคือ ข้อมูลโค้ดทั้ง 2 รายการต่อไปนี้จะใช้งานไม่ได้
// 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");
การโทรหา setFocusBehavior()
จะส่งไปในกรณีต่อไปนี้เช่นกัน
- แทร็กวิดีโอของสตรีมที่
getDisplayMedia()
แสดงผลไม่ใช่ "สด" - หลังจาก Promise ที่
getDisplayMedia()
แสดงผลเสร็จสิ้นแล้ว หากผู้ใช้แชร์หน้าจอ (ไม่ใช่แท็บหรือหน้าต่าง)
ตัวอย่าง
คุณใช้โฟกัสแบบมีเงื่อนไขได้โดยเรียกใช้การสาธิตใน Glitch อย่าลืมตรวจสอบซอร์สโค้ด
การตรวจหาองค์ประกอบ
หากต้องการตรวจสอบว่าระบบรองรับ CaptureController.setFocusBehavior()
หรือไม่ ให้ใช้
if (
"CaptureController" in window &&
"setFocusBehavior" in CaptureController.prototype
) {
// CaptureController.setFocusBehavior() is supported.
}
ความคิดเห็น
ทีม Chrome และชุมชนมาตรฐานเว็บอยากทราบความคิดเห็นของคุณเกี่ยวกับโฟกัสแบบมีเงื่อนไข
บอกเราเกี่ยวกับการออกแบบ
โฟกัสแบบมีเงื่อนไขไม่ทำงานตามที่คาดไว้ใช่ไหม หรือมีเมธอดหรือพร็อพเพอร์ตี้ที่ขาดหายไปซึ่งคุณต้องนำไปใช้กับไอเดียของคุณ หากมีคำถามหรือความคิดเห็นเกี่ยวกับรูปแบบการรักษาความปลอดภัย
- แจ้งปัญหาเกี่ยวกับข้อกำหนดใน GitHub repo หรือแสดงความคิดเห็นในปัญหาที่มีอยู่
พบปัญหาในการติดตั้งใช้งานใช่ไหม
หากพบข้อบกพร่องในการใช้งาน Chrome หรือการติดตั้งใช้งานแตกต่างจากข้อกําหนดหรือไม่
- รายงานข้อบกพร่องที่ https://new.crbug.com อย่าลืมใส่รายละเอียดให้มากที่สุดเท่าที่จะทำได้และคำแนะนำง่ายๆ ในการทำให้ซ้ำ Glitch ทำงานได้ดีสำหรับการแชร์โค้ด
แสดงการสนับสนุน
คุณวางแผนจะใช้การโฟกัสแบบมีเงื่อนไขไหม การสนับสนุนแบบสาธารณะของคุณจะช่วยให้ทีม Chrome จัดลำดับความสำคัญของฟีเจอร์ต่างๆ ได้ และแสดงให้เห็นว่าการสนับสนุนฟีเจอร์เหล่านี้สำคัญเพียงใดต่อผู้ให้บริการเบราว์เซอร์รายอื่นๆ
ส่งทวีตไปที่ @ChromiumDev และแจ้งให้เราทราบตำแหน่งและวิธีที่คุณใช้
ลิงก์ที่มีประโยชน์
ขอขอบคุณ
รูปภาพหลักโดย Elena Taranenko
ขอขอบคุณ Rachel Andrew ที่ตรวจสอบบทความนี้