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

בוחן פתע: מהי מטרת הפרמטר השלישי שמוענק ל-addEventListener()?

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

פונקציית addEventListener() עם אפשרויות הגדרה נוספות

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

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

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

אתם יכולים לשלב בין האפשרויות האלה בהתאם לתרחיש לדוגמה שלכם.

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

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

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

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

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

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

בדפדפנים Chrome מגרסה 55 ומעלה,‏ Firefox מגרסה 50 ומעלה ו-Safari מגרסה technology preview 7 ומעלה יש תמיכה מקורית באפשרות once.

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

תודה

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