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

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

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

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

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

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

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

הגדרת סמן כניתן ללחיצה

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

  • מגדירים את המאפיין gmpClickable לערך true.

TypeScript

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

JavaScript

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

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

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 כדי להסיר את הקליק event 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,
            gmpClickable: true,
        });
        // 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,
      gmpClickable: true,
    });

    // 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>

    <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>

כדאי לנסות דוגמה