הסימונים יהיו נגישים ונגישים

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

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

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

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

כדי לנווט בין הסמנים באמצעות המקלדת:

  1. השתמשו במקש Tab כדי להתמקד בסמן הראשון. אם יש כמה סמנים באותה המפה, תוכלו להשתמש במקשי החיצים כדי לעבור בין הסמנים.
  2. אם הסמן קליקבילי, מקישים על מקש Enter כדי "ללחוץ". אם לסמן יש חלון מידע, ניתן לפתוח אותו על ידי לחיצה, או על ידי הקשה על מקש Enter או על מקש הרווח. כשחלון המידע ייסגר, המיקוד יחזור לסמן המשויך.
  3. מקישים שוב על Tab כדי להמשיך לנווט בשאר הפקדים במפה.

הגדרת הסמן כקליקבילי

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

  • מגדירים את המאפיין gmpClickable כ-true.

TypeScript

const marker = new AdvancedMarkerElement({
    position,
    map,
    title: `${i + 1}. ${title}`,
    content: pin.element,
});

JavaScript

const marker = new AdvancedMarkerElement({
  position,
  map,
  title: `${i + 1}. ${title}`,
  content: pin.element,
});

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

TypeScript

// Add a click listener for each marker, and set up the info window.
marker.addListener('click', ({ domEvent, latLng }) => {
    const { target } = domEvent;
    infoWindow.close();
    infoWindow.setContent(marker.title);
    infoWindow.open(marker.map, marker);
});

JavaScript

// Add a click listener for each marker, and set up the info window.
marker.addListener("click", ({ domEvent, latLng }) => {
  const { target } = domEvent;

  infoWindow.close();
  infoWindow.setContent(marker.title);
  infoWindow.open(marker.map, marker);
});

  • כדי לבטל שוב את אפשרות הלחיצה על סמן, צריך לבצע קריאה ל-removeListener על מנת להסיר את ה-listener של אירועי קליק:

    // Remove the listener.
    google.maps.event.removeListener(clickListener);
    

כדי לשפר את הנגישות:

  • אפשר להגדיר טקסט תיאורי לסמן באמצעות האפשרות AdvancedMarkerElement.title.
  • הגדלת קנה המידה של הסמנים באמצעות המאפיין scale של PinElement.

השלמת קוד לדוגמה

הצגת הדוגמה המלאה לקוד המקור

TypeScript

async function initMap() {
    // Request needed libraries.
    const { Map, InfoWindow } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
    const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;

    const map = new Map(document.getElementById("map") as HTMLElement, {
        zoom: 12,
        center: { lat: 34.84555, lng: -111.8035 },
        mapId: '4504f8b37365c3d0',
    });

    // Set LatLng and title text for the markers. The first marker (Boynton Pass)
    // receives the initial focus when tab is pressed. Use arrow keys to
    // move between markers; press tab again to cycle through the map controls.
    const tourStops = [
        {
            position: { lat: 34.8791806, lng: -111.8265049 }, 
            title: "Boynton Pass"
        },
        {
            position: { lat: 34.8559195, lng: -111.7988186 }, 
            title: "Airport Mesa"
        },
        {
            position: { lat: 34.832149, lng: -111.7695277 }, 
            title: "Chapel of the Holy Cross"
        },
        {
            position: { lat: 34.823736, lng: -111.8001857 }, 
            title: "Red Rock Crossing"
        },
        {
            position: { lat: 34.800326, lng: -111.7665047 }, 
            title: "Bell Rock"
        },
    ];

    // Create an info window to share between markers.
    const infoWindow = new InfoWindow();

    // Create the markers.
    tourStops.forEach(({position, title}, i) => {
        const pin = new PinElement({
            glyph: `${i + 1}`,
            scale: 1.5,
        });
        const marker = new AdvancedMarkerElement({
            position,
            map,
            title: `${i + 1}. ${title}`,
            content: pin.element,
        });
        // Add a click listener for each marker, and set up the info window.
        marker.addListener('click', ({ domEvent, latLng }) => {
            const { target } = domEvent;
            infoWindow.close();
            infoWindow.setContent(marker.title);
            infoWindow.open(marker.map, marker);
        });
    });
}

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map, InfoWindow } = await google.maps.importLibrary("maps");
  const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary(
    "marker",
  );
  const map = new Map(document.getElementById("map"), {
    zoom: 12,
    center: { lat: 34.84555, lng: -111.8035 },
    mapId: "4504f8b37365c3d0",
  });
  // Set LatLng and title text for the markers. The first marker (Boynton Pass)
  // receives the initial focus when tab is pressed. Use arrow keys to
  // move between markers; press tab again to cycle through the map controls.
  const tourStops = [
    {
      position: { lat: 34.8791806, lng: -111.8265049 },
      title: "Boynton Pass",
    },
    {
      position: { lat: 34.8559195, lng: -111.7988186 },
      title: "Airport Mesa",
    },
    {
      position: { lat: 34.832149, lng: -111.7695277 },
      title: "Chapel of the Holy Cross",
    },
    {
      position: { lat: 34.823736, lng: -111.8001857 },
      title: "Red Rock Crossing",
    },
    {
      position: { lat: 34.800326, lng: -111.7665047 },
      title: "Bell Rock",
    },
  ];
  // Create an info window to share between markers.
  const infoWindow = new InfoWindow();

  // Create the markers.
  tourStops.forEach(({ position, title }, i) => {
    const pin = new PinElement({
      glyph: `${i + 1}`,
      scale: 1.5,
    });
    const marker = new AdvancedMarkerElement({
      position,
      map,
      title: `${i + 1}. ${title}`,
      content: pin.element,
    });

    // Add a click listener for each marker, and set up the info window.
    marker.addListener("click", ({ domEvent, latLng }) => {
      const { target } = domEvent;

      infoWindow.close();
      infoWindow.setContent(marker.title);
      infoWindow.open(marker.map, marker);
    });
  });
}

initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Advanced Marker Accessibility</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "beta"});</script>
  </body>
</html>

רוצה לנסות את הדוגמה