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

Cuando un marcador es arrastrable u ofrece la posibilidad de hacer clics, este puede responder a las entradas del teclado y el mouse. Esto significa que puedes usar estos controladores para desplazarte entre los distintos marcadores y moverlos, si son arrastrables. El texto especificado en la opción title es visible para los lectores de pantalla.

  • Si deseas configurar un marcador para que admita clics, agrega un controlador de eventos de clic.
  • Si deseas configurar un marcador para que sea arrastrable, establece la propiedad AdvancedMarkerView.draggable en true.
  • Si deseas establecer texto descriptivo para un marcador, usa la opción AdvancedMarkerView.title.

Configura un marcador para que admita clics

En el siguiente ejemplo, se muestra un mapa con cinco marcadores enfocables que admiten clics:

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

  1. Utiliza la tecla Tab para enfocar el primer marcador. Si hay varios en un mismo mapa, usa las teclas de flecha para desplazarte entre ellos.
  2. Si se puede hacer clic en el marcador, presiona la tecla Intro para "hacer clic". 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.

Consulta el código

TypeScript

function initMap() {
    const map = new google.maps.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 google.maps.InfoWindow();

    // Create the markers.
    tourStops.forEach(({position, title}, i) => {
        const pinView = new google.maps.marker.PinView({
            glyph: `${i + 1}`,
        });

        const marker = new google.maps.marker.AdvancedMarkerView({
            position,
            map,
            title: `${i + 1}. ${title}`,
            content: pinView.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);
        });
    });
}

declare global {
    interface Window {
        initMap: () => void;
    }
}

window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.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 google.maps.InfoWindow();

  // Create the markers.
  tourStops.forEach(({ position, title }, i) => {
    const pinView = new google.maps.marker.PinView({
      glyph: `${i + 1}`,
    });
    const marker = new google.maps.marker.AdvancedMarkerView({
      position,
      map,
      title: `${i + 1}. ${title}`,
      content: pinView.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);
    });
  });
}

window.initMap = 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;
}

[class$=api-load-alpha-banner] {
  display: none;
}

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>

    <!--
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=marker&v=beta"
      defer
    ></script>
  </body>
</html>

Prueba la muestra

Para volver a inhabilitar la posibilidad de hacer clics en un marcador, quita el objeto de escucha de eventos de clics.

// Adding the listener.
const clickListener = markerView.addListener('click', () => {...});

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

Configura un marcador para que sea arrastrable

Cuando la función de arrastre se encuentra habilitada, los usuarios pueden arrastrar marcadores en el mapa con el mouse o las teclas de flecha. Si deseas configurar un marcador para que sea arrastrable, establece la propiedad AdvancedMarkerView.draggable en true.

En el siguiente ejemplo, aparece un marcador arrastrable que muestra su posición actualizada en el mapa cuando finaliza el arrastre (se activa el evento dragend):

Para arrastrar un marcador con el teclado, haz lo siguiente:

  1. Presiona la tecla Tab hasta enfocar un marcador.
  2. Usa la tecla de flecha para desplazarte hasta el marcador deseado.
  3. Para activar la función de arrastre, presiona Opción + barra espaciadora, o bienOpción + Intro (Mac), o utiliza los comandos ALT + barra espaciadora o Alt + Intro (Windows).
  4. Usa las teclas de flecha para mover el marcador.
  5. Para colocar el marcador en una ubicación nueva, presiona la barra espaciadora o Intro. Esta acción también desactivará la función de arrastre.
  6. Para hacer esto y devolver el marcador a su posición anterior, presiona Esc.

Consulta el código

TypeScript

function initMap() {
    const map = new google.maps.Map(document.getElementById('map') as HTMLElement, {
        center: {lat: 37.39094933041195, lng: -122.02503913145092},
        zoom: 14,
        mapId: '4504f8b37365c3d0',
    });

    const infoWindow = new google.maps.InfoWindow();

    const draggableMarker = new google.maps.marker.AdvancedMarkerView({
        map,
        position: {lat: 37.39094933041195, lng: -122.02503913145092},
        draggable: true,
        title: "This marker is draggable.",
    });
    draggableMarker.addListener('dragend', (event) => {
        const position = draggableMarker.position as google.maps.LatLng;
        infoWindow.close();
        infoWindow.setContent(`Pin dropped at: ${position.lat()}, ${position.lng()}`);
        infoWindow.open(draggableMarker.map, draggableMarker);
    });

}

declare global {
    interface Window {
        initMap: () => void;
    }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 37.39094933041195, lng: -122.02503913145092 },
    zoom: 14,
    mapId: "4504f8b37365c3d0",
  });
  const infoWindow = new google.maps.InfoWindow();
  const draggableMarker = new google.maps.marker.AdvancedMarkerView({
    map,
    position: { lat: 37.39094933041195, lng: -122.02503913145092 },
    draggable: true,
    title: "This marker is draggable.",
  });

  draggableMarker.addListener("dragend", (event) => {
    const position = draggableMarker.position;

    infoWindow.close();
    infoWindow.setContent(
      `Pin dropped at: ${position.lat()}, ${position.lng()}`
    );
    infoWindow.open(draggableMarker.map, draggableMarker);
  });
}

window.initMap = 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;
}

[class$=api-load-alpha-banner] {
  display: none;
}

HTML

<html>
  <head>
    <title>Draggable Advanced Marker</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>

    <!--
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=marker&v=beta"
      defer
    ></script>
  </body>
</html>

Prueba la muestra

Establece texto descriptivo

Si deseas establecer texto descriptivo para un marcador de modo que sea visible para los lectores de pantalla, usa el atributo AdvancedMarkerView.title, como se muestra a continuación:

    const markerView = new google.maps.marker.AdvancedMarkerView({
        map,
        position: { lat: 37.4239163, lng: -122.0947209 },
        title: "Some descriptive text.",
    });

Cuando se configura el atributo title, el texto se vuelve visible para los lectores de pantalla y aparece cuando el mouse se coloca sobre el marcador.