IntersectionObserver' กำลังปรากฏตัว

IntersectionObservers จะแจ้งให้คุณทราบเมื่อองค์ประกอบที่พบเข้าหรือออกจากวิวพอร์ตของเบราว์เซอร์

การรองรับเบราว์เซอร์

  • Chrome: 51
  • Edge: 15.
  • Firefox: 55
  • Safari: 12.1

แหล่งที่มา

สมมติว่าคุณต้องการติดตามเมื่อองค์ประกอบใน DOM เข้าสู่วิวพอร์ตที่มองเห็น คุณอาจต้องการทําเช่นนี้เพื่อให้โหลดรูปภาพแบบ Lazy Load ได้ทันเวลา หรือเพราะคุณต้องทราบว่าผู้ใช้กําลังดูแบนเนอร์โฆษณาบางรายการอยู่หรือไม่ ซึ่งทำได้โดยการต่อเหตุการณ์การเลื่อนหรือใช้ตัวจับเวลาตามรอบและเรียกใช้ getBoundingClientRect() ในองค์ประกอบนั้น

อย่างไรก็ตาม วิธีการนี้ช้ามากเนื่องจากการเรียก getBoundingClientRect() แต่ละครั้งจะบังคับให้เบราว์เซอร์จัดเรียงหน้าเว็บใหม่ทั้งหมดและจะทำให้เว็บไซต์กระตุกอย่างมาก กรณีแทบจะเป็นไปไม่ได้เลยเมื่อคุณทราบว่าเว็บไซต์ของคุณกำลังโหลดใน iframe และคุณต้องการทราบว่าผู้ใช้จะเห็นองค์ประกอบเมื่อใด โมเดลต้นทางเดียวและเบราว์เซอร์จะไม่อนุญาตให้คุณเข้าถึงข้อมูลใดๆ จากหน้าเว็บที่มี iframe นี่เป็นปัญหาทั่วไป ตัวอย่างเช่น โฆษณามักจะโหลดโดยใช้ iframe

IntersectionObserver ออกแบบมาเพื่อทําให้การทดสอบการแสดงผลนี้มีประสิทธิภาพมากขึ้น และพร้อมใช้งานในเบราว์เซอร์สมัยใหม่ทั้งหมด IntersectionObserver ช่วยให้คุณทราบเมื่อองค์ประกอบที่สังเกตได้เข้าสู่หรือออกจากวิวพอร์ตของเบราว์เซอร์

ระดับการแชร์ iframe

วิธีสร้างIntersectionObserver

API ค่อนข้างเล็กและอธิบายได้ดีที่สุดโดยใช้ตัวอย่างต่อไปนี้

const io = new IntersectionObserver(entries => {
  console.log(entries);
}, {
  /* Using default options. Details below */
});

// Start observing an element
io.observe(element);

// Stop observing an element
// io.unobserve(element);

// Disable entire IntersectionObserver
// io.disconnect();

เมื่อใช้ตัวเลือกเริ่มต้นสําหรับ IntersectionObserver ระบบจะเรียกใช้การเรียกกลับทั้งเมื่อองค์ประกอบปรากฏขึ้นบางส่วนและเมื่อออกจากวิวพอร์ตโดยสมบูรณ์

หากคุณต้องการสังเกตองค์ประกอบหลายรายการ ก็อาจเป็นไปได้และแนะนำให้สังเกตองค์ประกอบหลายรายการโดยใช้อินสแตนซ์ IntersectionObserver เดียวกันโดยเรียกใช้ observe() หลายครั้ง

ระบบจะส่งพารามิเตอร์ entries ไปยังการเรียกกลับ ซึ่งเป็นอาร์เรย์ของออบเจ็กต์ IntersectionObserverEntry ออบเจ็กต์แต่ละรายการดังกล่าวจะมีข้อมูลจุดตัดที่อัปเดตแล้วสำหรับองค์ประกอบที่สังเกตได้รายการใดรายการหนึ่ง

🔽[IntersectionObserverEntry]
    time: 3893.92
    🔽rootBounds: ClientRect
        bottom: 920
        height: 1024
        left: 0
        right: 1024
        top: 0
        width: 920
    🔽boundingClientRect: ClientRect
    // ...
    🔽intersectionRect: ClientRect
    // ...
    intersectionRatio: 0.54
    🔽target: div#observee
    // ...

rootBounds คือผลลัพธ์ของการเรียก getBoundingClientRect() ในองค์ประกอบรูท ซึ่งเป็นวิวพอร์ตโดยค่าเริ่มต้น boundingClientRect คือผลลัพธ์ของ getBoundingClientRect() ที่เรียกใช้กับองค์ประกอบที่สังเกต intersectionRect คือจุดตัดของสี่เหลี่ยมผืนผ้า 2 รูปนี้ และบอกให้คุณทราบส่วนใดขององค์ประกอบที่สังเกตได้ซึ่งมองเห็นได้ intersectionRatio เกี่ยวข้องกันอย่างใกล้ชิด และบอกให้คุณทราบว่าองค์ประกอบหนึ่งๆ มองเห็นได้มากน้อยเพียงใด เมื่อทราบข้อมูลนี้แล้ว คุณจะสามารถใช้งานฟีเจอร์ต่างๆ เช่น โหลดชิ้นงานแบบทันท่วงทีก่อนที่ชิ้นงานจะปรากฏบนหน้าจอ อย่างมีประสิทธิภาพ

อัตราส่วนการซ้อนทับ

IntersectionObserver จะส่งข้อมูลแบบไม่พร้อมกัน และโค้ดการเรียกกลับจะทํางานในเธรดหลัก นอกจากนี้ ข้อกำหนดยังระบุว่าการติดตั้งใช้งาน IntersectionObserver ควรใช้ requestIdleCallback() ซึ่งหมายความว่าการติดต่อกลับที่คุณให้มาจะมีลำดับความสำคัญต่ำและจะดำเนินการโดยเบราว์เซอร์ในระหว่างที่ไม่มีความเคลื่อนไหว นี่เป็นการตัดสินใจด้านการออกแบบอย่างมีสติ

div ที่มีการเลื่อน

ไม่ค่อยชอบเลื่อนในองค์ประกอบเท่าไร ก็ไม่ได้อยากตัดสินและ IntersectionObserver ก็เช่นกัน ออบเจ็กต์ options จะใช้ตัวเลือก root ที่ช่วยให้คุณกําหนดทางเลือกอื่นแทนวิวพอร์ตเป็นรูทได้ โปรดทราบว่า root ต้องเป็นบรรพบุรุษขององค์ประกอบที่สังเกตได้ทั้งหมด

ตัดกันทั้งหมด

ไม่เอาด้วยหรอก นักพัฒนาแอปแย่ ซึ่งไม่ใช่การใช้งานรอบของ CPU ของผู้ใช้อย่างมีสติ ลองมาดูตัวอย่างตัวเลื่อนแบบอินฟินิตี้กัน ในกรณีนี้ เราขอแนะนำให้เพิ่ม Sentinel ลงใน DOM และสังเกต (และรีไซเคิล) รายการเหล่านั้น คุณควรเพิ่มรายการตรวจสอบใกล้กับรายการสุดท้ายในแถบเลื่อนแบบไม่สิ้นสุด เมื่อมีการแสดงผลเข้ามาแล้ว คุณสามารถใช้ Callback เพื่อโหลดข้อมูล สร้างรายการถัดไป แนบรายการดังกล่าวกับ DOM และเปลี่ยนตำแหน่งคำสังเกตการณ์ได้ตามความเหมาะสม หากนำผู้ดูแลกลับมาใช้ใหม่อย่างถูกต้อง ก็ไม่จำเป็นต้องโทรหา observe() เพิ่มเติม IntersectionObserver ทำงานอยู่เรื่อยๆ

ตัวเลื่อนแบบเลื่อนได้ไม่รู้จบ

โปรดอัปเดตเพิ่มเติม

ดังที่กล่าวไว้ก่อนหน้านี้ การเรียกกลับจะทริกเกอร์ 1 ครั้งเมื่อองค์ประกอบที่สังเกตพบเห็นได้บางส่วน และอีกครั้งเมื่อออกจากวิวพอร์ต วิธีนี้ช่วยให้ IntersectionObserver ตอบคําถามที่ว่า "องค์ประกอบ X อยู่ในมุมมองไหม" อย่างไรก็ตาม ในบางกรณี การดำเนินการดังกล่าวอาจไม่เพียงพอ

ตัวเลือก threshold จึงเข้ามามีบทบาท ซึ่งช่วยให้คุณกําหนดอาร์เรย์ของเกณฑ์ intersectionRatio ได้ ระบบจะเรียกใช้การเรียกกลับทุกครั้งที่ intersectionRatio ข้ามค่าใดค่าหนึ่งเหล่านี้ ค่าเริ่มต้นของ threshold คือ [0] ซึ่งอธิบายลักษณะการทำงานเริ่มต้น หากเปลี่ยน threshold เป็น [0, 0.25, 0.5, 0.75, 1] เราจะได้รับการแจ้งเตือนทุกครั้งที่มีการแสดงองค์ประกอบอีก 1 ใน 4 รายการ

ภาพเคลื่อนไหวของเกณฑ์

มีตัวเลือกอื่นไหม

ปัจจุบันมีตัวเลือกเพิ่มเติมเพียง 1 รายการนอกเหนือจากที่ระบุไว้ข้างต้น rootMargin ช่วยให้คุณระบุระยะขอบของรูทได้ ซึ่งช่วยให้คุณขยายหรือหดพื้นที่ที่ใช้สำหรับจุดตัดได้อย่างมีประสิทธิภาพ โดยระบุระยะขอบเหล่านี้โดยใช้สตริงสไตล์ CSS ในรูปแบบ "10px 20px 30px 40px" ซึ่งระบุระยะขอบด้านบน ขวา ล่าง และซ้ายตามลำดับ โดยสรุปแล้ว โครงสร้างตัวเลือก IntersectionObserver มีตัวเลือกต่อไปนี้

new IntersectionObserver(entries => {/* … */}, {
  // The root to use for intersection.
  // If not provided, use the top-level document's viewport.
  root: null,
  // Same as margin, can be 1, 2, 3 or 4 components, possibly negative lengths.
  // If an explicit root element is specified, components may be percentages of the
  // root element size.  If no explicit root element is specified, using a
  // percentage is an error.
  rootMargin: "0px",
  // Threshold(s) at which to trigger callback, specified as a ratio, or list of
  // ratios, of (visible area / total area) of the observed element (hence all
  // entries must be in the range [0, 1]).  Callback will be invoked when the
  // visible ratio of the observed element crosses a threshold in the list.
  threshold: [0],
});

<iframe> มายากล

IntersectionObserver ได้รับการออกแบบมาเพื่อบริการโฆษณาและวิดเจ็ตโซเชียลเน็ตเวิร์กโดยเฉพาะ ซึ่งใช้องค์ประกอบ <iframe> บ่อยครั้งและอาจได้รับประโยชน์จากการทราบว่าองค์ประกอบดังกล่าวอยู่ในมุมมองหรือไม่ หาก <iframe> สังเกตองค์ประกอบใดองค์ประกอบหนึ่ง ทั้งในการหมุน <iframe> และการเลื่อนหน้าต่างที่มี <iframe> จะทริกเกอร์การเรียกกลับในเวลาที่เหมาะสม อย่างไรก็ตาม ในกรณีหลัง ระบบจะตั้งค่า rootBounds เป็น null เพื่อหลีกเลี่ยงการรั่วไหลของข้อมูลในแหล่งที่มาต่างๆ

IntersectionObserver ไม่ได้เกี่ยวกับอะไร

สิ่งที่ควรทราบคือ IntersectionObserver ไม่ได้ออกแบบมาให้แสดงผลแบบพิกเซลสมบูรณ์หรือเวลาในการตอบสนองต่ำ การใช้งาน Google Analytics เพื่อใช้ฟีเจอร์อย่างภาพเคลื่อนไหวที่เป็นแบบเลื่อนได้เป็นหลักมีโอกาสล้มเหลว เนื่องจากข้อมูลจะไม่อัปเดต (บอกมาตรงๆ) เมื่อถึงเวลาที่คุณจะใช้งาน คําอธิบายมีรายละเอียดเพิ่มเติมเกี่ยวกับกรณีการใช้งานเดิมสําหรับ IntersectionObserver

ฉันจะดำเนินการได้มากน้อยเพียงใดในการติดต่อกลับ

ไม่มากก็น้อย: การใช้เวลาใน Callback นานเกินไปจะทำให้แอปล่าช้า - เป็นไปตามแนวทางปฏิบัติทั่วไปทั้งหมด

ออกไปผสานองค์ประกอบ

IntersectionObserver ใช้งานได้กับเบราว์เซอร์หลายรุ่นเนื่องจากมีให้บริการในเบราว์เซอร์ที่ทันสมัยทั้งหมด หากจำเป็น คุณสามารถใช้ polyfill ในเบราว์เซอร์รุ่นเก่าได้ ซึ่งอยู่ในที่เก็บข้อมูลของ WICG แน่นอนว่าคุณจะไม่ได้รับประโยชน์ด้านประสิทธิภาพจากการใช้โพลีฟีลนั้น ซึ่งการติดตั้งใช้งานแบบเนทีฟจะให้คุณได้

คุณเริ่มใช้ IntersectionObserver ได้เลย โปรดบอกเราว่าคุณคิดอะไรได้บ้าง