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