Làm cho điểm đánh dấu có thể nhấp và truy cập được

Bạn có thể làm cho điểm đánh dấu dễ tiếp cận hơn bằng cách bật xử lý sự kiện nhấp chuột, thêm văn bản mô tả cho trình đọc màn hình và điều chỉnh tỷ lệ đánh dấu.

  • Khi một điểm đánh dấu có thể nhấp (hoặc có thể kéo), điểm đánh dấu có thể phản hồi với bàn phím và thao tác đầu vào bằng chuột.
  • Văn bản được chỉ định trong tuỳ chọn title có thể đọc được bằng trình đọc màn hình và sẽ hiển thị khi người dùng giữ con trỏ chuột trên điểm đánh dấu.
  • Việc tăng kích thước của điểm đánh dấu sẽ làm giảm độ chính xác cần thiết để tương tác trên mọi thiết bị — đặc biệt là thiết bị màn hình cảm ứng — đồng thời cải thiện khả năng hỗ trợ tiếp cận. Điểm đánh dấu mặc định đáp ứng kích thước tối thiểu của WCAG AA là tiêu chuẩn nhưng dành cho các nhà phát triển muốn tuân thủ quy mô mục tiêu của WCAG AAA chuẩn, kích thước điểm đánh dấu sẽ được tăng lên.

Xem phần tuỳ chỉnh điểm đánh dấu cơ bản để tìm hiểu cách thay đổi điểm đánh dấu điều chỉnh tỷ lệ, thêm văn bản tiêu đề và nhiều tính năng khác.

Ví dụ sau đây cho thấy một bản đồ có năm điểm đánh dấu có thể nhấp vào, có thể làm tâm điểm bao gồm văn bản tiêu đề và đã được đặt theo tỷ lệ 1, 5x:

Cách điều hướng điểm đánh dấu bằng bàn phím:

  1. Sử dụng phím tab để tập trung vào điểm đánh dấu đầu tiên; nếu có nhiều các điểm đánh dấu trên cùng một bản đồ, hãy sử dụng các phím mũi tên để chuyển qua các điểm đánh dấu.
  2. Nếu điểm đánh dấu có thể nhấp được, nhấn phím enter để "nhấp". Nếu điểm đánh dấu có một cửa sổ thông tin, bạn có thể mở cửa sổ đó bằng cách nhấp hoặc bằng cách nhấn phím enter hoặc phím cách. Khi cửa sổ thông tin đóng, tiêu điểm sẽ quay lại điểm đánh dấu.
  3. Nhấn phím Tab một lần nữa để tiếp tục di chuyển qua các nút điều khiển còn lại trên bản đồ.

Tạo điểm đánh dấu có thể nhấp được

Phần này cho bạn biết cách làm cho điểm đánh dấu phản hồi sự kiện nhấp chuột. Để làm cho điểm đánh dấu có thể nhấp được:

  • Đặt thuộc tính gmpClickable thành 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,
});

  • Thêm trình nghe sự kiện nhấp chuột để phản hồi hoạt động đầu vào của người dùng.

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

  • Để làm cho điểm đánh dấu không nhấp vào được nữa, hãy gọi removeListener để xoá lượt nhấp trình xử lý sự kiện:

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

Để nâng cao hơn nữa khả năng hỗ trợ tiếp cận, hãy làm như sau:

  • Đặt văn bản mô tả cho điểm đánh dấu bằng cách sử dụng AdvancedMarkerElement.title .
  • Tăng tỷ lệ điểm đánh dấu bằng cách sử dụng thuộc tính scale của PinElement.

Đoạn mã mẫu hoàn chỉnh

Xem mã nguồn mẫu hoàn chỉnh

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>

Thử dùng mẫu