API จับภาพหน้าจอช่วยให้ผู้ใช้เลือกแท็บ หน้าต่าง หรือหน้าจอที่จะจับภาพเป็นสตรีมสื่อได้ จากนั้น สตรีมนี้จะถูกบันทึกหรือแชร์กับคนอื่นๆ ผ่านเครือข่าย เอกสารนี้แนะนำการโฟกัสแบบมีเงื่อนไข ซึ่งเป็นกลไกสำหรับเว็บแอปที่ใช้ควบคุมว่าระบบจะโฟกัสแท็บหรือหน้าต่างที่บันทึกไว้เมื่อเริ่มต้นการบันทึกหรือไม่ หรือให้หน้าการจับภาพจะยังคงอยู่
การสนับสนุนเบราว์เซอร์
การโฟกัสแบบมีเงื่อนไขพร้อมใช้งานใน Chrome 109
ที่มา
เมื่อเว็บแอปเริ่มจับภาพแท็บหรือหน้าต่าง เบราว์เซอร์จะตัดสินใจเองว่าควรทำให้พื้นผิวที่จับภาพไว้โดดเด่นขึ้นมา หรือหน้าจับภาพควรโฟกัสอยู่หรือไม่ คำตอบนั้นขึ้นอยู่กับเหตุผลที่เรียกใช้ getDisplayMedia()
และสุดท้ายแล้วผู้ใช้จะเลือกคำตอบอย่างไร
ลองใช้เว็บแอปการประชุมทางวิดีโอสมมติ เมื่ออ่าน track.getSettings().displaySurface
และอาจตรวจสอบแฮนเดิลการจับภาพ เว็บแอปการประชุมทางวิดีโอจะเข้าใจสิ่งที่ผู้ใช้เลือกแชร์ จากนั้นให้ทำดังนี้
- หากแท็บหรือหน้าต่างที่บันทึกไว้นั้นควบคุมจากระยะไกลได้ ให้โฟกัสการประชุมทางวิดีโอไว้
- หรือโฟกัสแท็บหรือหน้าต่างที่บันทึกไว้
ในตัวอย่างด้านบน เว็บแอปการประชุมทางวิดีโอจะยังคงมีจุดโฟกัสอยู่หากแชร์ชุดสไลด์ ซึ่งทำให้ผู้ใช้พลิกสไลด์ได้จากระยะไกล แต่หากผู้ใช้เลือกแชร์เครื่องมือแก้ไขข้อความ เว็บแอปการประชุมทางวิดีโอจะเปลี่ยนโฟกัสไปที่แท็บหรือหน้าต่างที่บันทึกไว้ทันที
การใช้ 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()
ได้หลายครั้งตามต้องการก่อนที่สัญญาจะสิ้นสุด หรือไม่เกิน 1 ครั้งหลังจากที่สัญญาสิ้นสุดลง การเรียกใช้ล่าสุดจะลบล้างคำขอก่อนหน้าทั้งหมด
แม่นยำยิ่งขึ้น:
- คำมั่นสัญญา 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 และอย่าลืมใส่รายละเอียดให้มากที่สุด รวมถึงวิธีการง่ายๆ ในการผลิตซ้ำ ภาพแตกเหมาะสำหรับการแชร์รหัส
แสดงการสนับสนุน
คุณวางแผนที่จะใช้การมุ่งเน้นแบบมีเงื่อนไขไหม การสนับสนุนแบบสาธารณะของคุณช่วยให้ทีม Chrome จัดลำดับความสำคัญของฟีเจอร์ และแสดงให้ผู้ให้บริการเบราว์เซอร์รายอื่นๆ เห็นว่าการสนับสนุนนั้นสำคัญเพียงใด
ส่งทวีตไปที่ @ChromiumDev และบอกเราว่าคุณใช้งานฟีเจอร์นี้ที่ไหนและอย่างไร
ลิงก์ที่มีประโยชน์
กิตติกรรมประกาศ
รูปภาพหลักโดย Elena Taranenko
ขอขอบคุณ Rachel Andrew ที่อ่านบทความนี้