Scrollend, אירוע JavaScript חדש

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

Adam Argyle
Adam Argyle

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

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

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

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

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

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

תמיכה בדפדפנים

  • Chrome: ‏ 114.
  • Edge: 114.
  • Firefox: ‏ 109.
  • Safari: לא נתמך.

מקור

רוצים לנסות?

פרטי האירוע

האירוע 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 והטמעה.