Thêm Google Maps có Điểm đánh dấu bằng JavaScript

Giới thiệu

Hướng dẫn này trình bày cách thêm bản đồ Google có điểm đánh dấu vào một trang web bằng HTML, CSS và JavaScript. Phần này cũng hướng dẫn bạn cách đặt các lựa chọn về bản đồ và cách sử dụng tính năng phân bổ thành phần để thêm nhãn vào bản đồ.

Dưới đây là bản đồ mà bạn sẽ tạo bằng hướng dẫn này. Điểm đánh dấu nằm ở Uluru (còn được gọi là Ayers Rock) trong Công viên Quốc gia Uluru-Kata Tjuta.

Bắt đầu

Có 3 bước để tạo một bản đồ Google có điểm đánh dấu trên trang web của bạn:

  1. Lấy khoá API
  2. Tạo trang HTML
  3. Thêm bản đồ có điểm đánh dấu

Bạn cần có một trình duyệt web. Chọn một trình duyệt phổ biến như Google Chrome (nên dùng), Firefox, Safari hoặc Edge, tuỳ thuộc vào nền tảng của bạn trong danh sách trình duyệt được hỗ trợ.

Bước 1: Lấy khoá API

Phần này giải thích cách xác thực ứng dụng của bạn với Maps JavaScript API bằng khoá API của riêng bạn.

Hãy làm theo các bước sau để lấy khoá API:

  1. Chuyển đến Bảng điều khiển Google Cloud.

  2. Tạo hoặc chọn một dự án.

  3. Nhấp vào Tiếp tục để bật API và mọi dịch vụ liên quan.

  4. Trên trang Thông tin xác thực, hãy lấy khoá API (và đặt các hạn chế đối với khoá API). Lưu ý: Nếu đã có một khoá API không bị hạn chế hoặc một khoá có các quy tắc hạn chế đối với trình duyệt, bạn có thể sử dụng khoá đó.

  5. Để ngăn chặn hành vi đánh cắp hạn mức và bảo mật khoá API, hãy xem phần Sử dụng khoá API.

  6. Bật tính năng thanh toán. Hãy xem phần Mức sử dụng và thanh toán để biết thêm thông tin.

  7. Sau khi bạn có khoá API, hãy thêm khoá đó vào đoạn mã sau bằng cách nhấp vào "YOUR_API_KEY". Sao chép và dán thẻ tập lệnh chương trình khởi động để sử dụng trên trang web của riêng bạn.

    <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: "YOUR_API_KEY",
        v: "weekly",
        // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
        // Add other bootstrap parameters as needed, using camel case.
      });
    </script>

Bước 2: Tạo trang HTML

Sau đây là mã cho một trang web HTML cơ bản:

<!DOCTYPE html>
<!--
 @license
 Copyright 2025 Google LLC. All Rights Reserved.
 SPDX-License-Identifier: Apache-2.0
-->

<html>
  <head>
    <title>Add a Map</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
    <!-- 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: "YOUR_API_KEY", v: "weekly"});</script>
  </head>
  <body>

    <!-- The map, centered at Uluru, Australia. -->
    <gmp-map center="-25.344,131.031" zoom="4" map-id="DEMO_MAP_ID">
    </gmp-map>

  </body>
</html>

Đây là một trang HTML rất cơ bản, sử dụng phần tử gmp-map để hiển thị bản đồ trên trang. Bản đồ sẽ trống vì chúng ta chưa thêm mã JavaScript nào.

Tìm hiểu về mã

Ở giai đoạn này trong ví dụ, chúng ta có:

  • Khai báo ứng dụng dưới dạng HTML5 bằng cách sử dụng nội dung khai báo !DOCTYPE html.
  • Đã tải Maps JavaScript API bằng trình tải khởi động.
  • Tạo một phần tử gmp-map để giữ bản đồ.

Khai báo ứng dụng của bạn là HTML5

Bạn nên khai báo một DOCTYPE thực trong ứng dụng web của mình. Trong các ví dụ ở đây, chúng tôi đã khai báo các ứng dụng của mình là HTML5 bằng cách sử dụng DOCTYPE HTML5 như minh hoạ bên dưới:

<!DOCTYPE html>

Hầu hết các trình duyệt hiện tại sẽ hiển thị nội dung được khai báo bằng DOCTYPE này ở "chế độ tiêu chuẩn", nghĩa là ứng dụng của bạn sẽ tuân thủ nhiều trình duyệt hơn. DOCTYPE cũng được thiết kế để giảm hiệu suất một cách từ từ; những trình duyệt không hiểu được thẻ này sẽ bỏ qua và sử dụng "chế độ tương thích" để hiển thị nội dung.

Xin lưu ý rằng một số CSS hoạt động trong chế độ tương thích không hợp lệ ở chế độ tiêu chuẩn. Cụ thể, tất cả các kích thước dựa trên tỷ lệ phần trăm đều phải kế thừa từ các phần tử khối gốc và nếu bất kỳ phần tử gốc nào trong số đó không chỉ định kích thước, thì chúng sẽ được giả định là có kích thước 0 x 0 pixel. Vì lý do đó, chúng tôi đưa ra tuyên bố style sau đây:

<style>
  gmp-map {
    height: 100%;
  }
  html, body {
    height: 100%;
    margin: 0;
    padding: 0;
  }
</style>

Tải Maps JavaScript API

Trình tải khởi động chuẩn bị API JavaScript của Maps để tải (không có thư viện nào được tải cho đến khi importLibrary() được gọi).

<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: "YOUR_API_KEY",
    v: "weekly",
    // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
    // Add other bootstrap parameters as needed, using camel case.
  });
</script>

Hãy xem Bước 3: Lấy khoá API để biết hướng dẫn về cách lấy khoá API của riêng bạn.

Ở giai đoạn này của hướng dẫn, một cửa sổ trống sẽ xuất hiện, chỉ hiển thị văn bản nhãn chưa được định dạng. Nguyên nhân là do chúng ta chưa thêm mã JavaScript nào.

Tạo một phần tử gmp-map

Để bản đồ xuất hiện trên một trang web, chúng ta phải dành riêng một vị trí cho bản đồ. Thông thường, chúng ta thực hiện việc này bằng cách tạo một phần tử gmp-map và lấy một tham chiếu đến phần tử này trong mô hình đối tượng tài liệu (DOM) của trình duyệt. Bạn cũng có thể dùng phần tử div để thực hiện việc này (tìm hiểu thêm), nhưng bạn nên dùng phần tử gmp-map.

Đoạn mã dưới đây xác định phần tử gmp-map và đặt các tham số center, zoommap-id.

<gmp-map center="-25.344,131.031" zoom="4" map-id="DEMO_MAP_ID">
</gmp-map>

Các lựa chọn centerzoom luôn là lựa chọn bắt buộc. Trong đoạn mã trên, thuộc tính center cho biết API nơi đặt tâm bản đồ và thuộc tính zoom chỉ định mức thu phóng cho bản đồ. Thu phóng: 0 là mức thu phóng thấp nhất và hiển thị toàn bộ Trái Đất. Đặt giá trị thu phóng cao hơn để phóng to Trái Đất ở độ phân giải cao hơn.

Mức thu phóng

Việc cung cấp bản đồ toàn bộ Trái Đất dưới dạng một hình ảnh duy nhất sẽ đòi hỏi một bản đồ khổng lồ hoặc một bản đồ nhỏ có độ phân giải rất thấp. Do đó, hình ảnh bản đồ trong Google Maps và Maps JavaScript API được chia thành các "ô" bản đồ và "mức thu phóng". Ở mức thu phóng thấp, một nhóm nhỏ các ô bản đồ sẽ bao phủ một khu vực rộng lớn; ở mức thu phóng cao hơn, các ô có độ phân giải cao hơn và bao phủ một khu vực nhỏ hơn. Danh sách sau đây cho biết mức độ chi tiết gần đúng mà bạn có thể thấy ở từng mức thu phóng:

  • 1: Thế giới
  • 5: Lục địa hoặc châu lục
  • 10: Thành phố
  • 15: Đường phố
  • 20: Toà nhà

3 hình ảnh sau đây phản ánh cùng một vị trí ở Tokyo ở mức thu phóng 0, 7 và 18.

Đoạn mã dưới đây mô tả CSS đặt kích thước của phần tử gmp-map.

/* Set the size of the gmp-map element that contains the map */
gmp-map {
    height: 400px; /* The height is 400 pixels */
    width: 100%; /* The width is the width of the web page */
}

Trong mã trên, phần tử style đặt kích thước của gmp-map. Đặt chiều rộng và chiều cao lớn hơn 0px để bản đồ xuất hiện. Trong trường hợp này, gmp-map được đặt thành chiều cao 400 pixel và chiều rộng 100% để hiển thị trên chiều rộng của trang web. Bạn nên luôn đặt kiểu chiều cao và chiều rộng một cách rõ ràng.

Kiểm soát việc chèn

Bạn có thể sử dụng tính năng phân bổ vị trí điều khiển để thêm các chế độ kiểm soát biểu mẫu HTML vào bản đồ. Vị trí là một vị trí được xác định trước trên bản đồ; hãy sử dụng thuộc tính slot để đặt vị trí cần thiết cho một phần tử và lồng các phần tử trong phần tử gmp-map. Đoạn mã sau đây cho thấy cách thêm nhãn HTML vào góc trên cùng bên trái của bản đồ.

<!-- The map, centered at Uluru, Australia. -->
<gmp-map center="-25.344,131.031" zoom="4" map-id="DEMO_MAP_ID">
  <div id="controls" slot="control-inline-start-block-start">
    <h3>My Google Maps Demo</h3>
  </div>
</gmp-map>

Bước 3: Thêm mã JavaScript

Phần này hướng dẫn bạn cách tải Maps JavaScript API vào một trang web và cách viết JavaScript của riêng bạn để sử dụng API này nhằm thêm một bản đồ có điểm đánh dấu.

TypeScript

async function initMap(): Promise<void> {
  //  Request the needed libraries.
  const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
    google.maps.importLibrary("maps") as Promise<google.maps.MapsLibrary>,
    google.maps.importLibrary("marker") as Promise<google.maps.MarkerLibrary>,
  ]);
  // Get the gmp-map element.
  const mapElement = document.querySelector(
    "gmp-map"
  ) as google.maps.MapElement;

  // Get the inner map.
  const innerMap = mapElement.innerMap;

  // Set map options.
  innerMap.setOptions({
    mapTypeControl: false,
  });

  // Add a marker positioned at the map center (Uluru).
  const marker = new AdvancedMarkerElement({
    map: innerMap,
    position: mapElement.center,
    title: "Uluru/Ayers Rock",
  });
}
initMap();

JavaScript

async function initMap() {
    //  Request the needed libraries.
    const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary("maps"),
        google.maps.importLibrary("marker"),
    ]);
    // Get the gmp-map element.
    const mapElement = document.querySelector("gmp-map");
    // Get the inner map.
    const innerMap = mapElement.innerMap;
    // Set map options.
    innerMap.setOptions({
        mapTypeControl: false,
    });
    // Add a marker positioned at the map center (Uluru).
    const marker = new AdvancedMarkerElement({
        map: innerMap,
        position: mapElement.center,
        title: "Uluru/Ayers Rock",
    });
}
initMap();

Đoạn mã trên sẽ thực hiện những việc sau khi initMap() được gọi:

  • Tải các thư viện mapsmarker.
  • Lấy phần tử bản đồ từ DOM.
  • Đặt thêm các lựa chọn về bản đồ trên bản đồ bên trong.
  • Thêm một điểm đánh dấu vào bản đồ.

Lấy đối tượng bản đồ và đặt các lựa chọn

innerMap đại diện cho một thực thể của lớp Map. Để đặt các lựa chọn cho bản đồ, hãy lấy thực thể innerMap từ phần tử bản đồ và gọi setOptions. Đoạn mã sau đây cho thấy cách lấy thực thể innerMap từ DOM, sau đó gọi setOptions:

// Get the gmp-map element.
const mapElement = document.querySelector(
  "gmp-map"
) as google.maps.MapElement;

// Get the inner map.
const innerMap = mapElement.innerMap;

// Set map options.
innerMap.setOptions({
  mapTypeControl: false,
});

Chờ bản đồ tải xong

Khi sử dụng phần tử gmp-map, bản đồ sẽ tải không đồng bộ. Điều này có thể dẫn đến tình trạng xung đột nếu các yêu cầu khác được thực hiện tại thời điểm khởi tạo (ví dụ: yêu cầu về vị trí địa lý hoặc yêu cầu về Thông tin chi tiết về địa điểm). Để đảm bảo mã của bạn chỉ chạy sau khi bản đồ được tải đầy đủ, hãy sử dụng trình xử lý sự kiện ở trạng thái rảnh addListenerOnce trong hàm khởi tạo, như minh hoạ ở đây:

// Do things once the map has loaded.
google.maps.event.addListenerOnce(innerMap, 'idle', () => {
    // Run this code only after the map has loaded.
    console.log("The map is now ready!");
});

Việc này đảm bảo rằng mã của bạn chỉ chạy sau khi bản đồ đã tải; trình xử lý chỉ được kích hoạt một lần trong vòng đời của ứng dụng.

Mã ví dụ hoàn chỉnh

Xem mã ví dụ hoàn chỉnh tại đây:

TypeScript

async function initMap(): Promise<void> {
  //  Request the needed libraries.
  const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
    google.maps.importLibrary("maps") as Promise<google.maps.MapsLibrary>,
    google.maps.importLibrary("marker") as Promise<google.maps.MarkerLibrary>,
  ]);
  // Get the gmp-map element.
  const mapElement = document.querySelector(
    "gmp-map"
  ) as google.maps.MapElement;

  // Get the inner map.
  const innerMap = mapElement.innerMap;

  // Set map options.
  innerMap.setOptions({
    mapTypeControl: false,
  });

  // Add a marker positioned at the map center (Uluru).
  const marker = new AdvancedMarkerElement({
    map: innerMap,
    position: mapElement.center,
    title: "Uluru/Ayers Rock",
  });
}
initMap();

JavaScript

async function initMap() {
    //  Request the needed libraries.
    const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary("maps"),
        google.maps.importLibrary("marker"),
    ]);
    // Get the gmp-map element.
    const mapElement = document.querySelector("gmp-map");
    // Get the inner map.
    const innerMap = mapElement.innerMap;
    // Set map options.
    innerMap.setOptions({
        mapTypeControl: false,
    });
    // Add a marker positioned at the map center (Uluru).
    const marker = new AdvancedMarkerElement({
        map: innerMap,
        position: mapElement.center,
        title: "Uluru/Ayers Rock",
    });
}
initMap();

CSS

/*
 * Always set the map height explicitly to define the size of the div element
 * that contains the map.
 */
gmp-map {
  height: 100%;
}

/*
   * Optional: Makes the sample page fill the window.
   */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Add a Map</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
    <!-- 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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
  </head>
  <body>
    <!-- The map, centered at Uluru, Australia. -->
    <gmp-map center="-25.344,131.031" zoom="4" map-id="DEMO_MAP_ID">
      <div id="controls" slot="control-inline-start-block-start">
        <h3>My Google Maps Demo</h3>
      </div>
    </gmp-map>
  </body>
</html>

Thử dùng mẫu

Tìm hiểu thêm về điểm đánh dấu:

Mẹo và cách khắc phục sự cố

  • Tìm hiểu thêm về cách lấy toạ độ vĩ độ/kinh độ hoặc chuyển đổi địa chỉ thành toạ độ địa lý.
  • Bạn có thể điều chỉnh các lựa chọn như kiểu và thuộc tính để tuỳ chỉnh bản đồ. Để biết thêm thông tin về cách tuỳ chỉnh bản đồ, hãy đọc hướng dẫn về định kiểuvẽ trên bản đồ.
  • Sử dụng Bảng điều khiển Công cụ cho nhà phát triển trong trình duyệt web để kiểm thử và chạy mã, đọc báo cáo lỗi và giải quyết các vấn đề về mã.
  • Sử dụng các phím tắt sau để mở bảng điều khiển trong Chrome:
    Command+Option+J (trên máy Mac) hoặc Control+Shift+J (trên Windows).
  • Làm theo các bước bên dưới để lấy toạ độ vĩ độ và kinh độ của một vị trí trên Google Maps.

    1. Mở Google Maps trong trình duyệt.
    2. Nhấp chuột phải vào vị trí chính xác trên bản đồ mà bạn cần toạ độ.
    3. Chọn Đây là gì? trong trình đơn theo bối cảnh xuất hiện. Bản đồ sẽ hiển thị một thẻ ở cuối màn hình. Tìm toạ độ theo vĩ độ và kinh độ ở hàng cuối cùng của thẻ.
  • Bạn có thể chuyển đổi một địa chỉ thành toạ độ vĩ độ và kinh độ bằng cách sử dụng dịch vụ Mã hoá địa lý. Các hướng dẫn dành cho nhà phát triển cung cấp thông tin chi tiết về cách bắt đầu sử dụng dịch vụ Mã hoá địa lý.