נכנסים לתצוגה של IntersectionObserver

אירועי IntersectionObserver מאפשרים לכם לדעת מתי רכיב שנצפה נכנס או יוצא מחלון התצוגה של הדפדפן.

Browser Support

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

Source

נניח שאתם רוצים לעקוב אחרי הרגעים שבהם רכיב ב-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, פונקציית ה-callback תופעל גם כשהרכיב נכנס לטווח הראייה באופן חלקי וגם כשהוא יוצא ממנו לגמרי.

אם צריך לעקוב אחרי כמה רכיבים, אפשר גם מומלץ לעקוב אחרי כמה רכיבים באמצעות אותה מופע IntersectionObserver, על ידי קריאה ל-observe() כמה פעמים.

הפרמטר entries מועבר ל-callback, שהוא מערך של אובייקטים מסוג 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 הוא הצומת של שני המלבנים האלה, והוא מראה איזה חלק של הרכיב שנצפה גלוי. המאפיין intersectionRatio קשור מאוד למאפיין הקודם, והוא מציין כמה מהרכיב גלוי. בעזרת המידע הזה, עכשיו תוכלו להטמיע תכונות כמו טעינת נכסים בזמן אמת לפני שהם יהיו גלויים במסך. ביעילות.

יחס הצטלבות.

IntersectionObservers מעבירים את הנתונים שלהם באופן אסינכררוני, וקוד ה-callback יפעל ב-thread הראשי. בנוסף, במפרט מצוין בפועל ש-IntersectionObserver צריך להשתמש ב-requestIdleCallback(). כלומר, הקריאה למספר החזרה שלכם תהיה בעדיפות נמוכה והדפדפן יבצע אותה במהלך זמן השהיה. זוהי החלטה מודעת של העיצוב.

גלילה של divs

אני לא אוהב לגלול בתוך אלמנט, אבל אני לא כאן כדי לשפוט, וגם IntersectionObserver לא. האובייקט options מקבל אפשרות root שמאפשרת להגדיר חלופה למיקום הצפייה כשורש. חשוב לזכור ש-root צריך להיות אב קדמון של כל הרכיבים שנצפו.

חותכים את כל הדברים!

לא! מפתח גרוע! זה לא שימוש מודע במחזורי המעבד של המשתמשים. ניקח לדוגמה גלילה אינסופית: בתרחיש כזה, מומלץ מאוד להוסיף חיישנים ל-DOM ולעקוב אחריהם (ולמחזר אותם!). צריך להוסיף גלאי קרוב לפריט האחרון בגלילה האינסופית. כשהחיישן הזה מופיע, אפשר להשתמש ב-callback כדי לטעון נתונים, ליצור את הפריטים הבאים, לצרף אותם ל-DOM ולהזיז את החיישן בהתאם. אם מחזירים את השומר לשימוש חוזר כראוי, אין צורך בקריאה נוספת ל-observe(). ה-IntersectionObserver ממשיך לפעול.

גלילה מתמשכת

עוד עדכונים, בבקשה

כפי שצוין קודם, פונקציית ה-callback תופעל פעם אחת כשהרכיב שנצפה נכנס באופן חלקי לתצוגה, ופעם נוספת כשהוא יוצא מטווח התצוגה. כך הפונקציה IntersectionObserver מספקת תשובה לשאלה "האם רכיב X נמצא בתצוגה?". עם זאת, בתרחישים לדוגמה מסוימים, יכול להיות שזה לא מספיק.

כאן נכנסת לתמונה האפשרות threshold. הוא מאפשר להגדיר מערך של ערכי סף של intersectionRatio. הקריאה החוזרת תתבצע בכל פעם ש-intersectionRatio חוצה את אחד מהערכים האלה. ערך ברירת המחדל של threshold הוא [0], ולכן זוהי התנהגות ברירת המחדל. אם נשנה את הערך של threshold ל-[0, 0.25, 0.5, 0.75, 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> magic

אירועי IntersectionObserver תוכננו במיוחד עבור שירותי מודעות וווידג'טים של רשתות חברתיות, שבהם נעשה שימוש לעיתים קרובות ברכיבי <iframe>, ויכול להיות שיועילו מהמידע על כך שהם גלויים. אם <iframe> מזהה אחד מהאלמנטים שלו, גלילה ב-<iframe> וגלילה בחלון שמכיל את <iframe> יפעילו את פונקציית ה-callback בזמנים המתאימים. עם זאת, במקרה השני, הערך של rootBounds יוגדר כ-null כדי למנוע דליפת נתונים בין מקורות.

מה IntersectionObserver לא עוסק?

חשוב לזכור ש-IntersectionObserver לא מיועד להציג תמונות ברזולוציה גבוהה או להציג נתונים בזמן אמת. שימוש בהם כדי להטמיע תכונות כמו אנימציות שתלובות בגלילה נכשל בוודאות, כי הנתונים יהיו – באופן מדויק – לא מעודכנים עד שתשתמשו בהם. הסרטון מכיל פרטים נוספים על התרחישים לדוגמה המקוריים של IntersectionObserver.

כמה עבודה אפשר לבצע בשיחה החוזרת?

בקצרה: אם תימשכו את הזמן של הקריאה החוזרת יותר מדי, האפליקציה תתעכב – כל השיטות הנפוצות רלוונטיות.

קדימה, ערבבו את הרכיבים

התמיכה בדפדפנים ב-IntersectionObserver טובה, כי היא זמינה בכל הדפדפנים המודרניים. במקרה הצורך, אפשר להשתמש ב-polyfill בדפדפנים ישנים יותר. ה-polyfill זמין במאגר של WICG. ברור שלא תקבלו את יתרונות הביצועים שמתקבלים מהטמעה ילידית באמצעות ה-polyfill הזה.

אפשר להתחיל להשתמש ב-IntersectionObserver כבר עכשיו. נשמח לדעת מה המצאת.