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