Scrollend, אירוע JavaScript חדש

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

לפני האירוע scrollend, לא הייתה דרך מהימנה לזהות שגלילה הושלמה. המשמעות היא שהאירועים יופעלו באיחור או בזמן שהאצבע של המשתמש עדיין על המסך. חוסר האמינות הזה בזיהוי של סיום הגלילה הוביל לבאגים ולחוויית משתמש גרועה.

לפני
document.onscroll = event => {
  clearTimeout(window.scrollEndTimer)
  window.scrollEndTimer = setTimeout(callback, 100)
}

הדבר הטוב ביותר שאפשר לעשות עם אסטרטגיית setTimeout() הוא לדעת אם הגלישה הופסקה ב-100ms. כך האירוע דומה יותר לאירוע מסוג 'הגלילה הושהתה' ולא לאירוע מסוג 'הגלילה הסתיימה'.

אחרי האירוע scrollend, הדפדפן מבצע בשבילכם את כל ההערכות המורכבות האלה.

אחרי
document.onscrollend = event => {}

זה החלק הטוב. מתוזמנים בצורה מושלמת ומלאים בתנאים משמעותיים לפני ההעברה.

Browser Support

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

Source

רוצים לנסות?

פרטי האירוע

האירוע scrollend מופעל במקרים הבאים: - הדפדפן לא מניע יותר את הגלילה או מתרגם אותה. - המשתמש הפסיק לגעת במסך. - סמן המשתמש שיחרר את פס ההזזה. - המשתמש הפסיק ללחוץ על המקש. - הגלילה למקטע הסתיימה. - השלמת הצמדת הגלילה. - scrollTo() הושלם. - המשתמש גולל את אזור התצוגה החזותי.

האירוע scrollend לא מופעל במקרים הבאים: - התנועות של המשתמש לא גרמו לשינויים במיקום הגלילה (לא התרחש תרגום). - scrollTo() לא הניב תרגום.

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

שימוש באירוע

כמו באירועי גלילה אחרים, יש כמה דרכים לרשום מאזינים.

addEventListener("scrollend", (event) => {
  // scroll ended
});

aScrollingElement.addEventListener("scrollend", (event) => {
  // scroll ended
});

לחלופין, אפשר להשתמש במאפיין האירוע:

document.onscrollend = (event) => {
  // scroll ended
};

aScrollingElement.onscrollend = (event) => {
  // scroll ended
};

תוספים למילוי חוסרים ושיפורים פרוגרסיביים

אם אתם רוצים להשתמש באירוע החדש הזה כבר עכשיו, הנה העצה הטובה ביותר שלנו. אתם יכולים להמשיך להשתמש באסטרטגיה הנוכחית שלכם לסיום גלילה (אם יש לכם אחת) ובתחילת הגלילה לבדוק את התמיכה באמצעות:

'onscrollend' in window
// true, if available

הפונקציה תדווח על true או false, בהתאם לכך שהדפדפן מציע את האירוע. בעזרת הבדיקה הזו אפשר להסתעף בקוד:

if ('onscrollend' in window) {
  document.onscrollend = callback
}
else {
  document.onscroll = event => {
    clearTimeout(window.scrollEndTimer)
    window.scrollEndTimer = setTimeout(callback, 100)
  }
}

זהו התחלה טובה לשיפור הדרגתי של האירוע scrollend כשהוא יהיה זמין. אפשר גם לנסות polyfill (NPM) שיצרתי, שמשתמש בדפדפן בצורה הטובה ביותר:

import {scrollend} from "scrollyfills"

// then use scrollend as if it's existed this whole time
document.onscrollend = callback

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

תרחישים לדוגמה

מומלץ להימנע מביצוע פעולות שדורשות חישובים כבדים בזמן הגלילה. כך אפשר להשתמש בזיכרון ובעיבוד הרבה יותר כדי שהגלילה תהיה חלקה. שימוש באירוע scrollend הוא הזמן המושלם להציג הודעה ולבצע את העבודה הקשה, כי הגלישה כבר לא מתבצעת.

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

נניח שמשתמש מחליק אימייל. אחרי שהם מסיימים להחליק, תוכלו לבצע את הפעולה על סמך המקום שאליו הם גוללו.

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

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

תודה למהדי קדמי (Mehdi Kazemi) על העבודה ההנדסית בנושא הזה, ולרוברט פלאק (Robert Flack) על ההנחיות בנושא API והטמעה.