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 se puede hacer clic en un marcador (o se puede arrastrar), este puede responder a las entradas del teclado y del mouse.
  • El texto especificado en la opción title es legible para los lectores de pantalla y se muestra cuando un usuario coloca 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 la personalización básica de marcadores para obtener información sobre cómo cambiar la escala del marcador, agregar el texto del título y mucho más.

En el siguiente ejemplo, se muestra un mapa con cinco marcadores enfocables en los que se puede hacer clic, que incluyen texto del título y que se establecieron en una escala de 1.5x:

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 los 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 las entradas 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 a fin de quitar el objeto de escucha de eventos de clic:

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

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

  • Usa la opción AdvancedMarkerElement.title para establecer texto descriptivo para un marcador.
  • 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>
    <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>

Prueba la muestra