היה פעם מעבד אירוע (event listener)

ג'ף פוזניק
ג'ף פוזניק

בוחן פתאום: מה המטרה של הפרמטר השלישי שמועבר אל addEventListener()?

אם חשבתם ש-addEventListener() לוקח רק שני פרמטרים, או אולי תמיד מקודד את הערך false בתוך הקוד, עם הבנה לא ברורה שיש לכך קשר עם בועות, אל תתביישו?

AddEventListener() שניתן להגדיר יותר

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

אנחנו שמחים להודיע שבגרסת Chrome 55 נוספה תמיכה באפשרות once באובייקט התצורה, לצד האפשרות passive (הוטמעה ב-Chrome 51) ואפשרויות capture (הוטמעה ב-Chrome 49). לדוגמה:

element.addEventListener('click', myClickHandler, {
    once: true,
    passive: true,
    capture: true
});

תוכלו לשלב ולהתאים את האפשרויות האלה בהתאם לתרחיש השימוש שלכם בפועל.

היתרונות של פינוי מקום אחריכם

זה התחביר לשימוש באפשרות once החדשה, אבל מה תרוויח מכך? בקיצור, מקבלים event listener שמותאם לתרחישי שימוש מסוג 'אחד ובוצע'.

כברירת מחדל, פונקציות event listener מופיעות אחרי ההפעלה הראשונה שלהן. זה מה שאתם רוצים כשיש סוגים מסוימים של אירועים, למשל, לחצנים שניתן ללחוץ עליהם מספר פעמים. עם זאת, שימושים אחרים ב-event listener לא הכרחיים, והם עלולים להוביל להתנהגות לא רצויה אם יש לכם קריאה חוזרת (callback) שחייבת להתבצע פעם אחת בלבד. למפתחים לשמירה על היגיינה תמיד הייתה אפשרות להשתמש ב-removeEventListener() כדי לנקות פריטים באופן מפורש, באמצעות תבניות כמו:

element.addEventListener('click', function cb(event) {
    // ...one-time handling of the click event...
    event.currentTarget.removeEventListener(event.type, cb);
});

הקוד המקביל, שבו משתמשים בפרמטר החדש של once, נקי יותר ולא מחייב אתכם לעקוב אחרי שם האירוע (event.type, בדוגמה הקודמת) או הפניה לפונקציית הקריאה החוזרת (cb):

element.addEventListener('click', function(event) {
    // ...one-time handling of the click event...
}, {once: true});

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

function setUpListeners() {
    var data = ['one', 'two', '...etc.'];

    window.addEventListener('load', function() {
    doSomethingWithSomeData(data);
    // data is now part of the callback's scope.
    });
}

כברירת מחדל, היקף הקריאה החוזרת (callback) של אירועי load מסוג event listener מסתיים בסיום ההפעלה, למרות שלא משתמשים בה שוב. מכיוון שנעשה שימוש במשתנה data בתוך הקריאה החוזרת (callback), הוא גם יישאר בהיקף ולא ייאסף אשפה. עם זאת, אם הקריאה החוזרת הוסרה דרך הפרמטר once, גם הפונקציה עצמה וגם כל דבר שנשאר פעיל דרך ההיקף שלה עשויים להיות מועמדים לאיסוף אשפה.

תמיכת דפדפן

ב-Chrome בגרסאות 55 ואילך, ב-Firefox 50 ואילך ובגרסת טרום-ההשקה (Preview) של הטכנולוגיה 7+, יש תמיכה מובנית באפשרות once.

ספריות רבות של ממשק המשתמש של JavaScript מספקות שיטות נוחות ליצירת מאזיני אירועים, ובחלקן יש קיצורי דרך להגדרה של אירועים חד-פעמיים – כשהאחרונה מביניהן היא השיטה one() של jquery. אפשר למצוא גם פוליפיל כחלק מהספרייה של אנדריאה גיאמרצ'י dom4.

תודה

תודה ל-Ingvar Stepanyan על המשוב לגבי הקוד לדוגמה בפוסט הזה.