Sự kiện

Chọn nền tảng: Android iOS JavaScript

Trang này mô tả các sự kiện lỗi và sự kiện trên giao diện người dùng mà bạn có thể theo dõi và xử lý theo phương thức lập trình.

Sự kiện trên giao diện người dùng

JavaScript trong trình duyệt được hướng sự kiện, có nghĩa là JavaScript phản hồi các hoạt động tương tác bằng cách tạo sự kiện và kỳ vọng một chương trình để nghe các sự kiện thú vị. Có hai loại sự kiện:

  • Sự kiện người dùng (chẳng hạn như sự kiện "nhấp chuột") được truyền từ DOM đến API JavaScript của Maps. Các sự kiện này riêng biệt và khác với sự kiện DOM chuẩn.
  • Thông báo về thay đổi trạng thái MVC phản ánh các thay đổi trong Maps JavaScript API và được đặt tên theo quy ước property_changed.

Mỗi đối tượng API JavaScript của Maps xuất một số sự kiện được đặt tên. Những chương trình quan tâm đến một số sự kiện nhất định sẽ đăng ký trình nghe sự kiện JavaScript cho các sự kiện đó và thực thi mã khi các sự kiện đó được nhận bởi gọi addListener() để đăng ký trình xử lý sự kiện trên đối tượng.

Mẫu sau đây sẽ cho bạn biết những sự kiện mà google.maps.Map đã kích hoạt khi bạn tương tác với bản đồ.

Để xem danh sách đầy đủ các sự kiện, hãy tham khảo Tài liệu tham khảo API JavaScript của Maps. Sự kiện được liệt kê trong một phần riêng cho mỗi đối tượng chứa sự kiện.

Sự kiện giao diện người dùng

Một số đối tượng trong API JavaScript của Maps được thiết kế nhằm phản hồi vào các sự kiện của người dùng, chẳng hạn như sự kiện chuột hoặc bàn phím. Ví dụ: đây là một số người dùng các sự kiện mà đối tượng google.maps.marker.AdvancedMarkerElement có thể theo dõi:

  • 'click'
  • 'drag'
  • 'dragend'
  • 'dragstart'
  • 'gmp-click'

Để xem danh sách đầy đủ, hãy tham khảo AdvancedMarkerElement . Những sự kiện này có thể trông giống như các sự kiện DOM chuẩn, nhưng thực ra chúng là một phần của API Maps JavaScript. Do các trình duyệt khác nhau triển khai các mô hình sự kiện DOM khác nhau, API JavaScript của Maps cung cấp những cơ chế này để theo dõi và phản hồi các sự kiện DOM mà không cần xử lý các đặc điểm khác nhau trên nhiều trình duyệt. Những sự kiện này cũng thường truyền đối số trong sự kiện, ghi nhận trạng thái giao diện người dùng nào đó (chẳng hạn như vị trí chuột).

Các thay đổi về trạng thái MVC

Các đối tượng MVC thường chứa trạng thái. Bất cứ khi nào thuộc tính của một đối tượng thay đổi, API JavaScript của Maps sẽ kích hoạt sự kiện mà thuộc tính đã thay đổi. Ví dụ: API sẽ kích hoạt sự kiện zoom_changed trên một bản đồ khi mức thu phóng của bản đồ thay đổi cấp độ. Bạn có thể chặn những thay đổi về trạng thái này bằng cách gọi addListener() để đăng ký trình xử lý sự kiện trên đối tượng.

Sự kiện của người dùng và thay đổi về trạng thái MVC có thể trông giống nhau, nhưng bạn thường muốn để xử lý chúng theo cách khác nhau trong mã của bạn. Ví dụ: các sự kiện MVC không vượt qua đối số trong sự kiện của chúng. Bạn sẽ muốn kiểm tra thuộc tính mà đã thay đổi khi trạng thái MVC thay đổi bằng cách gọi lệnh gọi Phương thức getProperty trên đối tượng đó.

Xử lý sự kiện

Để đăng ký nhận thông báo về sự kiện, hãy sử dụng addListener() trình xử lý sự kiện. Phương thức đó nhận một sự kiện để theo dõi, và một để gọi khi sự kiện được chỉ định xảy ra.

Ví dụ: Sự kiện trên bản đồ và điểm đánh dấu

Mã sau đây kết hợp sự kiện của người dùng với sự kiện thay đổi trạng thái. Chúng tôi đính kèm một trình xử lý sự kiện cho một điểm đánh dấu để thu phóng bản đồ khi được nhấp vào. Chúng tôi cũng thêm một trình xử lý sự kiện cho bản đồ cho các thay đổi đối với thuộc tính center và xoay bản đồ trở lại điểm đánh dấu sau 3 giây kể từ khi nhận được Sự kiện center_changed:

TypeScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;

  const myLatlng = { lat: -25.363, lng: 131.044 };

  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: myLatlng,
      mapId: "DEMO_MAP_ID",
    }
  );

  const marker = new google.maps.marker.AdvancedMarkerElement({
    position: myLatlng,
    map,
    title: "Click to zoom",
  });

  map.addListener("center_changed", () => {
    // 3 seconds after the center of the map has changed, pan back to the
    // marker.
    window.setTimeout(() => {
      map.panTo(marker.position as google.maps.LatLng);
    }, 3000);
  });

  marker.addListener("click", () => {
    map.setZoom(8);
    map.setCenter(marker.position as google.maps.LatLng);
  });
}

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
  const myLatlng = { lat: -25.363, lng: 131.044 };
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: myLatlng,
    mapId: "DEMO_MAP_ID",
  });
  const marker = new google.maps.marker.AdvancedMarkerElement({
    position: myLatlng,
    map,
    title: "Click to zoom",
  });

  map.addListener("center_changed", () => {
    // 3 seconds after the center of the map has changed, pan back to the
    // marker.
    window.setTimeout(() => {
      map.panTo(marker.position);
    }, 3000);
  });
  marker.addListener("click", () => {
    map.setZoom(8);
    map.setCenter(marker.position);
  });
}

initMap();
Xem ví dụ

Dùng thử mẫu

Mẹo: Nếu bạn đang cố gắng phát hiện một thay đổi trong khung nhìn, hãy nhớ sử dụng sự kiện bounds_changed cụ thể thay vì thành phần zoom_changedcenter_changed sự kiện. Vì API JavaScript của Maps kích hoạt các sự kiện sau một cách độc lập, getBounds() có thể không báo cáo các kết quả hữu ích cho đến khi khung nhìn đã thay đổi một cách có căn cứ. Nếu bạn muốn getBounds() sau sự kiện như vậy, hãy nhớ nghe bounds_changed sự kiện.

Ví dụ: Sự kiện chỉnh sửa hình dạng và kéo

Khi chỉnh sửa hoặc kéo một hình dạng, sự kiện sẽ được kích hoạt khi hoàn tất hành động. Để biết danh sách các sự kiện và một số đoạn mã, hãy xem Hình dạng.

Chế độ xem ví dụ (rectangle-event.html)

Truy cập đối số trong các sự kiện trên giao diện người dùng

Sự kiện giao diện người dùng trong API JavaScript của Maps thường truyền một đối số sự kiện, Trình nghe sự kiện có thể truy cập, ghi chú trạng thái giao diện người dùng khi đã xảy ra. Ví dụ: sự kiện 'click' trên giao diện người dùng thường vượt qua MouseEvent chứa thuộc tính latLng biểu thị vị trí được nhấp trên bản đồ. Lưu ý rằng hành vi này chỉ dành riêng cho giao diện người dùng sự kiện; Các thay đổi về trạng thái MVC không truyền đối số vào các sự kiện của chúng.

Bạn có thể truy cập các đối số của sự kiện trong trình nghe sự kiện theo cách tương tự bạn sẽ truy cập vào thuộc tính của một đối tượng. Ví dụ sau đây thêm một sự kiện trình nghe cho bản đồ và tạo một điểm đánh dấu khi người dùng nhấp vào bản đồ tại vị trí được nhấp.

TypeScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
  const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;

  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: -25.363882, lng: 131.044922 },
      mapId: "DEMO_MAP_ID",
    }
  );

  map.addListener("click", (e) => {
    placeMarkerAndPanTo(e.latLng, map);
  });
}

function placeMarkerAndPanTo(latLng: google.maps.LatLng, map: google.maps.Map) {
  new google.maps.marker.AdvancedMarkerElement({
    position: latLng,
    map: map,
  });
  map.panTo(latLng);
}

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary(
    "marker",
  );
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
    mapId: "DEMO_MAP_ID",
  });

  map.addListener("click", (e) => {
    placeMarkerAndPanTo(e.latLng, map);
  });
}

function placeMarkerAndPanTo(latLng, map) {
  new google.maps.marker.AdvancedMarkerElement({
    position: latLng,
    map: map,
  });
  map.panTo(latLng);
}

initMap();
Xem ví dụ

Dùng thử mẫu

Sử dụng quy tắc đóng trong Trình nghe sự kiện

Khi thực thi một trình nghe sự kiện, bạn nên sử dụng cả hai dữ liệu riêng tư và cố định được gắn với một đối tượng. JavaScript thì không hỗ trợ "riêng tư" dữ liệu thực thể nhưng lại hỗ trợ trạng thái đóng cho phép các hàm bên trong truy cập vào bên ngoài biến. Việc đóng rất hữu ích trong trình nghe sự kiện để truy cập vào các biến không thường được gắn vào đối tượng khi sự kiện xảy ra.

Ví dụ sau đây sử dụng một hàm đóng trong trình nghe sự kiện để gán thông điệp bí mật cho một bộ điểm đánh dấu. Nhấp vào từng điểm đánh dấu sẽ tiết lộ một phần của thư bí mật, không có trong chính nó.

TypeScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;

  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: -25.363882, lng: 131.044922 },
      mapId: "DEMO_MAP_ID",
    }
  );

  const bounds: google.maps.LatLngBoundsLiteral = {
    north: -25.363882,
    south: -31.203405,
    east: 131.044922,
    west: 125.244141,
  };

  // Display the area between the location southWest and northEast.
  map.fitBounds(bounds);

  // Add 5 markers to map at random locations.
  // For each of these markers, give them a title with their index, and when
  // they are clicked they should open an infowindow with text from a secret
  // message.
  const secretMessages = ["This", "is", "the", "secret", "message"];
  const lngSpan = bounds.east - bounds.west;
  const latSpan = bounds.north - bounds.south;

  for (let i = 0; i < secretMessages.length; ++i) {
    const marker = new google.maps.marker.AdvancedMarkerElement({
      position: {
        lat: bounds.south + latSpan * Math.random(),
        lng: bounds.west + lngSpan * Math.random(),
      },
      map: map,
    });

    attachSecretMessage(marker, secretMessages[i]);
  }
}

// Attaches an info window to a marker with the provided message. When the
// marker is clicked, the info window will open with the secret message.
function attachSecretMessage(
  marker: google.maps.marker.AdvancedMarkerElement,
  secretMessage: string
) {
  const infowindow = new google.maps.InfoWindow({
    content: secretMessage,
  });

  marker.addListener("click", () => {
    infowindow.open(marker.map, marker);
  });
}

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
    mapId: "DEMO_MAP_ID",
  });
  const bounds = {
    north: -25.363882,
    south: -31.203405,
    east: 131.044922,
    west: 125.244141,
  };

  // Display the area between the location southWest and northEast.
  map.fitBounds(bounds);

  // Add 5 markers to map at random locations.
  // For each of these markers, give them a title with their index, and when
  // they are clicked they should open an infowindow with text from a secret
  // message.
  const secretMessages = ["This", "is", "the", "secret", "message"];
  const lngSpan = bounds.east - bounds.west;
  const latSpan = bounds.north - bounds.south;

  for (let i = 0; i < secretMessages.length; ++i) {
    const marker = new google.maps.marker.AdvancedMarkerElement({
      position: {
        lat: bounds.south + latSpan * Math.random(),
        lng: bounds.west + lngSpan * Math.random(),
      },
      map: map,
    });

    attachSecretMessage(marker, secretMessages[i]);
  }
}

// Attaches an info window to a marker with the provided message. When the
// marker is clicked, the info window will open with the secret message.
function attachSecretMessage(marker, secretMessage) {
  const infowindow = new google.maps.InfoWindow({
    content: secretMessage,
  });

  marker.addListener("click", () => {
    infowindow.open(marker.map, marker);
  });
}

initMap();
Xem ví dụ

Dùng thử mẫu

Nhận và đặt thuộc tính trong Trình xử lý sự kiện

Không có sự kiện thay đổi trạng thái MVC nào trong thẻ hệ thống sự kiện Maps JavaScript API đối số khi sự kiện được kích hoạt. (Sự kiện người dùng truyền đối số có thể kiểm tra.) Nếu bạn cần kiểm tra một tài sản khi thay đổi trạng thái MVC, bạn nên gọi lệnh gọi biến thể Phương thức getProperty() trên đối tượng đó. Chiến dịch này việc kiểm tra sẽ luôn truy xuất trạng thái hiện tại của MVC mà có thể không phải là trạng thái khi sự kiện được kích hoạt lần đầu tiên.

Lưu ý: Việc thiết lập rõ ràng tài sản trong một trình xử lý sự kiện phản hồi sự thay đổi trạng thái cụ thể đó thuộc tính có thể tạo ra hành vi khó đoán và/hoặc không mong muốn. Chế độ cài đặt một thuộc tính như vậy sẽ kích hoạt một sự kiện mới và nếu bạn luôn bạn có thể đặt thuộc tính trong trình xử lý sự kiện này, nhưng bạn có thể phải tạo một thuộc tính vòng lặp vô hạn.

Trong ví dụ bên dưới, chúng ta thiết lập một trình xử lý sự kiện để phản hồi thu phóng các sự kiện bằng cách hiển thị cửa sổ thông tin hiển thị mức độ đó.

TypeScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;

  const originalMapCenter = new google.maps.LatLng(-25.363882, 131.044922);
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: originalMapCenter,
    }
  );

  const infowindow = new google.maps.InfoWindow({
    content: "Change the zoom level",
    position: originalMapCenter,
  });

  infowindow.open(map);

  map.addListener("zoom_changed", () => {
    infowindow.setContent("Zoom: " + map.getZoom()!);
  });
}

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  const originalMapCenter = new google.maps.LatLng(-25.363882, 131.044922);
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: originalMapCenter,
  });
  const infowindow = new google.maps.InfoWindow({
    content: "Change the zoom level",
    position: originalMapCenter,
  });

  infowindow.open(map);
  map.addListener("zoom_changed", () => {
    infowindow.setContent("Zoom: " + map.getZoom());
  });
}

initMap();
Xem ví dụ

Dùng thử mẫu

Nghe sự kiện DOM

Mô hình sự kiện API JavaScript của Maps tạo và quản lý mô hình của riêng nó sự kiện tùy chỉnh. Tuy nhiên, DOM (Mô hình đối tượng tài liệu) trong trình duyệt cũng tạo và gửi các sự kiện của riêng mình, tuỳ theo mô hình sự kiện trình duyệt đang được sử dụng. Nếu bạn muốn thu thập và trả lời những sự kiện, API JavaScript của Maps sẽ cung cấp addDomListener() để theo dõi và liên kết với các sự kiện DOM.

Phương thức tiện lợi này có chữ ký như sau:

addDomListener(instance:Object, eventName:string, handler:Function)

trong đó instance có thể là bất kỳ phần tử DOM nào được trình duyệt hỗ trợ, bao gồm:

  • Các thành viên phân cấp của DOM như window hoặc document.body.myform
  • Các phần tử được đặt tên, chẳng hạn như document.getElementById("foo")

Lưu ý rằng addDomListener() vượt qua sự kiện được chỉ định cho trình duyệt, trình duyệt này sẽ xử lý theo mô hình sự kiện DOM của trình duyệt; tuy nhiên, hầu hết các trình duyệt hiện đại đều hỗ trợ DOM Cấp 2. (Để biết thêm thông tin về các sự kiện ở cấp DOM, hãy xem Các cấp độ DOM của Mozilla reference.)

TypeScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;

  const mapDiv = document.getElementById("map") as HTMLElement;
  const map = new google.maps.Map(mapDiv, {
    zoom: 8,
    center: new google.maps.LatLng(-34.397, 150.644),
  });

  // We add a DOM event here to show an alert if the DIV containing the
  // map is clicked.
  google.maps.event.addDomListener(mapDiv, "click", () => {
    window.alert("Map was clicked!");
  });
}

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  const mapDiv = document.getElementById("map");
  const map = new google.maps.Map(mapDiv, {
    zoom: 8,
    center: new google.maps.LatLng(-34.397, 150.644),
  });

  // We add a DOM event here to show an alert if the DIV containing the
  // map is clicked.
  google.maps.event.addDomListener(mapDiv, "click", () => {
    window.alert("Map was clicked!");
  });
}

initMap();

HTML

<html>
  <head>
    <title>Listening to DOM Events</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: "weekly"});</script>
  </body>
</html>
Xem ví dụ

Dùng thử mẫu

Mặc dù mã ở trên là mã Maps JavaScript API, Phương thức addDomListener() liên kết với đối tượng window của trình duyệt và cho phép API giao tiếp với các đối tượng bên ngoài Miền thông thường của API.

Xoá trình nghe sự kiện

Để xoá một trình nghe sự kiện cụ thể, bạn phải chỉ định trình nghe đó cho một biến. Sau đó, bạn có thể gọi removeListener(), truyền tên biến mà trình nghe được chỉ định.

var listener1 = marker.addListener('click', aFunction);

google.maps.event.removeListener(listener1);

Để xoá tất cả trình nghe khỏi một phiên bản cụ thể, hãy gọi clearInstanceListeners(), truyền tên thực thể.

var listener1 = marker.addListener('click', aFunction);
var listener2 = marker.addListener('mouseover', bFunction);

// Remove listener1 and listener2 from marker instance.
google.maps.event.clearInstanceListeners(marker);

Cách xoá tất cả trình nghe cho một loại sự kiện cụ thể của một phiên bản cụ thể: gọi clearListeners(), truyền tên thực thể và sự kiện .

marker.addListener('click', aFunction);
marker.addListener('click', bFunction);
marker.addListener('click', cFunction);

// Remove all click listeners from marker instance.
google.maps.event.clearListeners(marker, 'click');

Để biết thêm thông tin, hãy tham khảo tài liệu tham khảo dành cho không gian tên google.maps.event.

Nghe lỗi xác thực

Nếu bạn muốn phát hiện lỗi xác thực bằng cách lập trình (ví dụ: để tự động gửi một beacon), bạn có thể chuẩn bị một hàm callback. Nếu hàm toàn cục sau được định nghĩa thì hàm này sẽ được gọi khi xác thực không thành công. function gm_authFailure() { /* Code */ };