auxclick מגיע ל-Chrome 55

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

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

אפשר לבנות מודל של האינטראקציות השונות האלה, אם הוא קצת מורכב, באמצעות האזנה ל-event listener אחת ל-click. תצטרכו לבדוק באופן מפורש את המאפיין button של MouseEvent כדי לראות אם הוא הוגדר כ-0 שמייצג את הלחצן הראשי, לעומת כל דבר אחר, כאשר 1 בדרך כלל מייצג את הלחצן האמצעי וכן הלאה. עם זאת, מפתחים לא רבים מגיעים רחוק במידה רבה כדי לבדוק באופן מפורש את הנכס button, ומוביל לקוד שמטפל בכל click באופן זהה, ללא קשר ללחצן שעליו לחץ המשתמש.

החל מ-Chrome 55, סוג חדש של MouseEvent, שנקרא auxclick, מופעל בתגובה לקליקים על לחצן שאינו ראשי. לצד האירוע החדש מופיע שינוי תואם בהתנהגות של האירוע click: הוא יופעל רק כשלוחצים על לחצן העכבר הראשי. אנחנו מקווים שהשינויים האלה יאפשרו למפתחי אתרים לכתוב בקלות רכיבי handler של אירועים שמגיבים רק לסוג הקליקים שחשובים להם, בלי שיצטרכו לבדוק באופן ספציפי את המאפיין MouseEvent.button.

הפחתת תוצאות חיוביות שקריות

כפי שצוין, אחת מהמטרות ליצירת auxclick הייתה להימנע מפריסה של גורמי handler בהתאמה אישית של click שמבטלים בטעות את ההתנהגות 'middle-click-opens-a-tab'. לדוגמה, נניח שכתבתם גורם handler של אירועים מסוג click, שמשתמש ב-History API כדי לשכתב את סרגל המיקום ולהטמיע ניווטים מותאמים אישית בדף יחיד. הוא עשוי להיראות כך:

document.querySelector('#my-link').addEventListener('click', event => {
    event.preventDefault();
    // ...call history.pushState(), use client-side rendering, etc....
});

יכול להיות שהלוגיקה בהתאמה אישית תפעל כמו שצריך כשהיא מופעלת על ידי הלחצן הראשי של העכבר, אבל אם הקוד הזה פועל כשלוחצים על לחצן אמצעי, זו למעשה תוצאה חיובית שגויה. לפני ההתנהגות החדשה, פעולה זו תמנע את פעולת ברירת המחדל לפתיחת כרטיסייה חדשה, שמנוגד לציפיות של המשתמשים. אפשר לחפש את event.button === 0 באופן מפורש בתחילת ה-handler, ולהריץ את הקוד רק במקרה כזה, קל לשכוח או אף פעם לא להבין שצריך לעשות את זה.

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

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

תמיכה ותאימות בדפדפן

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

בינתיים, המפתחים לא צריכים לחכות עד ש-auxclick יהיה זמין באופן נרחב כדי לפעול לפי כמה שיטות מומלצות לטיפול באירועי עכבר. אם תקדישו את הזמן לבדיקת הערך של המאפיין MouseEvent.button בתחילת הגורם המטפל באירועים של click, תוכלו לוודא שאתם מבצעים את הפעולה המתאימה. התבנית הבאה תטפל בצורה שונה בקליקים ראשיים ובקליקים עזר, בין אם קיימת תמיכה מובנית ב-auxclick ובין אם לא:

function handlePrimaryClick(event) {
    // ...code to handle the primary button click...
}

function handleAuxClick(event) {
    // ...code to handle the auxiliary button click….
}

document.querySelector('#my-link').addEventListener('click', event => {
    if (event.button === 0) {
    return handlePrimaryClick(event);
    }


    // This provides fallback behavior in browsers without auxclick.
    return handleAuxClick(event);
});

// Explicitly listen for auxclick in browsers that support it.
document.querySelector('#my-link').addEventListener('auxclick', handleAuxClick);