แชร์หน้าจอได้ดียิ่งขึ้นด้วยโฟกัสแบบมีเงื่อนไข

François Beaufort
François Beaufort

Browser Support

  • Chrome: 109.
  • Edge: 109.
  • Firefox: not supported.
  • Safari: not supported.

Source

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 ที่ตรวจสอบบทความนี้