מוחקים את פונקציות הזמן הקצוב ומבטלים את הבאגים שלהן. זהו האירוע שאתם באמת צריכים: scrollend.
לפני האירוע scrollend
, לא הייתה דרך אמינה לזהות שבוצעה גלילה. המשמעות היא שהאירועים יופעלו באיחור או בזמן שהאצבע של המשתמש עדיין על המסך. חוסר האמינות הזה בזיהוי של סיום הגלילה בפועל הוביל לבאגים ולחוויית משתמש גרועה.
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
הדבר הטוב ביותר שאפשר לעשות עם שיטת הבידינג setTimeout()
הוא לדעת אם הגולש הפסיק לגלול ב-100ms
. כך נראה אירוע שגלילה מושהית, ולא אירוע שגלילה הסתיימה.
אחרי האירוע scrollend
, הדפדפן מבצע בשבילכם את כל ההערכות המורכבות האלה.
document.onscrollend = event => {…}
אלה הדברים הטובים. מתוזמנים בצורה מושלמת ומלאים בתנאים משמעותיים לפני ההעברה.
רוצים לנסות?
פרטי האירוע
האירוע 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 והטמעה.