Cómo configurar los marcadores para que sean accesibles y permitan la posibilidad de hacer clics

Puedes hacer que los marcadores sean más accesibles habilitando el control de eventos de clic, agregando texto descriptivo para los lectores de pantalla y ajustando la escala del marcador.

  • Cuando un marcador ofrece la posibilidad de hacer clics (o arrastrar), puede responder a las entradas del teclado y del mouse.
  • Los lectores de pantalla pueden leer el texto especificado en la opción title, que se mostrará cuando un usuario coloque el puntero del mouse sobre el marcador.
  • Aumentar el tamaño de los marcadores reduce la precisión que se requiere para interactuar con ellos en todos los dispositivos (en especial en dispositivos de pantalla táctil) y mejora la accesibilidad. Los marcadores predeterminados cumplen con el estándar WCAG para el tamaño mínimo AA, pero, para los desarrolladores que desean cumplir con el estándar WCAG AAA objetivo de tamaño, se debe aumentar el tamaño del marcador.

Consulta Personalización básica de los marcadores para aprender a cambiar la escala de los marcadores, agregar texto de título y mucho más.

En el siguiente ejemplo, se muestra un mapa con cinco marcadores seleccionables que admiten clics que incluyen texto del título y se configuraron en una escala de 1.5 veces:

Para navegar por los marcadores con el teclado, sigue estos pasos:

  1. Utiliza la tecla Tab para posicionarte en el primer marcador. Si hay varios marcadores en un mismo mapa, usa las teclas de flecha para desplazarte entre ellos.
  2. Si el marcador admite la posibilidad de hacer clics, presiona la tecla Intro para hacerlo. Si un marcador tiene una ventana de información, puedes hacer clic en él o bien presionar la tecla Intro o la barra espaciadora para abrirla. Cuando se cierre la ventana de información, el foco volverá al marcador asociado.
  3. Vuelve a presionar la tecla Tab para seguir moviéndote por el resto de los controles del mapa.

Configura un marcador para que admita clics

En esta sección, se muestra cómo hacer que los marcadores respondan a eventos de clic. Para configurar un marcador para que admita clics, sigue estos pasos:

  • Establece la propiedad gmpClickable en 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,
});

  • Agrega un objeto de escucha de eventos de clic para responder a la entrada del usuario.

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);
});

  • Para volver a inhabilitar la posibilidad de hacer clics en un marcador, llama a removeListener para quitar el objeto de escucha de eventos de clics:

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

Para mejorar aún más la accesibilidad, haz lo siguiente:

  • Establece texto descriptivo para un marcador con la opción AdvancedMarkerElement.title.
  • Aumenta la escala del marcador con la propiedad scale de PinElement.

Ejemplo de código completo

Consulta el ejemplo de código fuente completo

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>

Prueba la muestra