מרחשוון

הרפתקאות מפת בתי הספר באתר אורט – פרק ז’, נגישות

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

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

  1. פתירת התנגשות עם תוסף נגישות
  2. וידוא שהמפה נגישה באמצעות מקלדת

תוסף נגישות מתעלם מהמפה

לשם הנגשת האתר, התקנו את התוסף עוזר נגישות (WAH). הוא עובד אחלה, אבל ב-QA של העמוד הזה התגלתה בעיה: כשבוחרים לשנות את ניגודיות הצבעים ובוחרים צבע רקע, האזור של המפה נצבע גם הוא בצבע הרקע הזה, ומסתיר את המפה.

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

למה זה קורה? מפני שכשבוחרים צבע רקע, התוסף מוסיף style לכל האלמנטים בעמוד – למעט תמונות – שמוגדר בו בתור background-color את הצבע שבחרנו (מוגדר לו גם color כדי להתאים את הניגודיות. נחזור לזה מאוחר יותר). ה-style הזה מתווסף גם לאלמנטים של המפה, וכך, פוף! נעלמת לה המפה.

הבנתי שהפתרון צריך להיות לבטל את ה-style הזה בכל האלמנטים של המפה, מפני שהתוסף לא יודע שהמפה צריכה להתנהג כמו תמונה. אבל איך מבטלים את ה-style שהתוסף מחיל?

החלת רקע שקוף עם JS

מאחר שעבר כבר זמן, אני לא זוכרת למה לא הצליח לי פשוט להגדיר מראש לכל תתי האלמנטים של המפה רקע שקוף ב-CSS, אבל זה היה המצב – לא הצלחתי להשתלט על זה ב-CSS, ולכן עברתי לחיפוש פתרון ב-JS.

כדי לדעת איך בדיוק להגדיר את הרקע השקוף ב-JS, הסתכלתי ב-JS של התוסף כדי לראות מה הקוד שמחיל את הסטייל החדש על כל האלמנטים. מצאתי את זה ב-wp-content/plugins/wp-accessibility-helper/assets/js/wp-accessibility-helper.js:


jQuery('body :not(.wahcolor), body').css({
    'background-color': Cookies.get('wahBgColor'),
    'color': Cookies.get('wahFontColor')
});

הבנתי שהפונקציה שאכתוב צריכה למצוא את אלמנט המפה, ולהגדיר לו, ולכל תתי האלמנטים שלו, background-color: transparent.

מציאת האירוע המתאים להגדרה

חיפשתי אירוע שקורה כשהסטיילים של אלמנט משתנים כדי שאוכל להצמיד אליו את הפונקציה שאכתוב. התברר שזה לא פשוט כמו אירוע של עכבר או מקלדת: ניטור של שינויים ב-DOM הוא אופרה שונה לחלוטין – אין לו אירוע שאפשר להצמיד לו פונקציה! מוזר אך מעניין. לא היה לי מושג מה עושים במקרה כזה. אבל לא אלמן ישראל – חיפוש קצר בגוגל שלח אותי ל-SO, ושם גיליתי את MutationObserver, שכשמו כן הוא: עוקב אחרי שינויים ב-DOM. הקוד בתשובה ההיא נתן לי את הפתרון שהייתי צריכה, והתאמתי אותה לצרכיי.
באופן קוסמי, אחרי כמה ימים נתקלתי במאמר ב-SamshingMagazine שמסביר ומדגים שימוש באובייקט הזה. המאמר חיזק את מה כבר הבנתי לבד, וגם הוסיף עוד רקע והסברים והדגמות שונות שעזרו לי עוד יותר להבין.

אז הפונקציה החמודה שלי יוצרת אוביקט מסוג MutationObserver, מודיעה לו שאנחנו אורבים לשינויים שקורים במאפיין style בתגית שיש לה id=page, ומגדירה פונקציה שתיקרא כשהשינוי מתרחש – פונקציית callback. פונקציית ה-callback (שקראתי לה בשם המיוחד והמקורי callback), בודקת שהשינוי התרחש על מאפיין מסוג style, מחילה את הרקע השקוף על המפה, עוברת בלולאה על כל תתי האלמנטים של המפה (חוץ מכמה, שאתייחס להם מיד אחרי הפונקציה) ומחילה עליהם את ה-CSS.

זו הפונקציה שמחילה את ה-CSS של הרקע השקוף:


/* Watch accessibility css change of background color */
let elementToWatchForAccessibility = "page";
bodyCssChange();

function bodyCssChange() {
    // Select the node that will be observed for mutations
    var targetNode = document.getElementById('page');
    // Options for the observer (which mutations to observe)
    var config = {
        attributes: true,
        attributeFilter: ['style'],
        characterData: true,
        childList: false,
        subtree: false,
        attributeOldValue: true,
        characterDataOldValue: true
    };

    // Callback function to execute when mutations are observed
    var index = 0;
    var callback = function (mutationsList) {
        for (var mutation of mutationsList) {
            if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
                console.log(typeof map !== 'undefined');
                $('#map').css({
                    'background-color': 'transparent'
                });
                let currElements = $('#map').children();
                while (currElements.length > 0) {
                    currElements.css({
                        'background-color': 'transparent'
                    });
                    currElements = currElements.children();
                }

            }
        }
    };

    // Create an observer instance linked to the callback function
    var observer = new MutationObserver(callback);

    // Start observing the target node for configured mutations
    observer.observe(targetNode, config);

}

חלונית, הלנו את אם לצרינו?

אמרתי “על כל תתי האלמנטים”? אז התכוונתי – חוץ מאלה שרקע שקוף לא עושה להם טוב. למשל, החלונית שנפתחת כשלוחצים על סמן (דיברנו על החלונית בפרק הקודם). החלונית הזאת, מאחר שיש בה טקסט, טוב יהיה אם תישאר עם ההגדרות שתוסף הנגישות מחיל עליה. ולכן בתוך הלולאה יש לי בדיקה אם האלמנט הנוכחי הוא מסוג חלונית. רק אם לא, ה-CSS מוחל עליה.

וזו הפונקציה שבודקת אם האלמנט הוא כזה שצריך להישאר עם ה-CSS של תוסף הנגישות:


let infoWindowWrapperClass = 'info_window_wrapper';
    /**
     * Return if current element should change style.
     * Needed to keep the accessibility style for the infoWindow
     */
    function shouldStyleChange(currElements) {
        let shouldChangeStyle = true;
        currElements.each(function () {
            if ($(this).get(0) === $('.' + infoWindowWrapperClass).get(0)) {
                shouldChangeStyle = false;
            }
        });
        return shouldChangeStyle;
    }

חלונית חדשה, ברוך בואך

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

מצד תכנות טהור ומודולריות, הדרך שעשיתי את זה היא לא מוצלחת ולא מומלצת בעליל: שילבתי את הפונקציה שמתייחסת לנגישות בתוך הקוד שבונה את החלון. במקום זה היה עליי להפעיל אותה בנפרד, אחרי שה-HTML של החלונית כבר בנוי, באופן non intrusive לבנייה. אולי יום אחד אחזור ואתקן את זה. בינתיים זה הקוד:

בפונקציה openInfoWindow, בשורה שיוצרת את ה-div החיצוני של החלונית, קראתי לפונקציה שמטפלת בנגישות:

let infoWindowWrapperBegin = "<div class='" + infoWindowWrapperClass + "'" + updateInfowWindowForA11y() + ">";

וזו הפונקציה:

function updateInfowWindowForA11y() {
    let pageStyle = $('#' + elementToWatchForAccessibility).attr('style');
    if (pageStyle !== "") {
        return "style='" + pageStyle + "'";
    }
}

מעבר טאב על סמנים במפה

לא רק עם תוסף הנגישות הייתה בעיה. גם עם נגישות המפה עצמה הייתה לנו בעיה, ולצערנו לא מצאתי דרך לפתור אותה.

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

 

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

4 תגובות על “הרפתקאות מפת בתי הספר באתר אורט – פרק ז’, נגישות

    1. אלרון, תודה רבה על התגובה וכל הכבוד על ההתמדה!
      שמחה שיכולתי להחכים אותך.

כתבו תגובה ללאה כהן Cancel reply

כתובת הדוא"ל שלכם לא תוצג.