Các phần tử Place Details

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

Phần tử Thông tin chi tiết về địa điểm và Phần tử Thông tin chi tiết về địa điểm thu gọn là các phần tử HTML hiển thị thông tin chi tiết về một địa điểm:

Phần tử Chi tiết về địa điểm

Nhấp vào một điểm đánh dấu trên bản đồ để xem thông tin chi tiết về địa điểm trong một Phần tử thông tin chi tiết về địa điểm.

PlaceDetailsElement hỗ trợ nhiều phần tử nội dung, bao gồm cả giờ mở cửa đầy đủ, trang web, số điện thoại, nội dung tóm tắt biên tập, điểm nổi bật theo loại, bài đánh giá, mã cộng và danh sách tính năng.

Để hiển thị thông tin chi tiết về địa điểm trên bản đồ, hãy thêm phần tử gmp-place-details vào phần tử gmp-map trên trang HTML. Thêm một phần tử con, gmp-place-details-place-request, để chọn địa điểm. Đây có thể là một đối tượng Địa điểm, một mã địa điểm hoặc tên tài nguyên của Địa điểm theo định dạng "places/{place_id}":

<gmp-map center="47.759737, -122.250632" zoom="16" map-id="DEMO_MAP_ID">
    <gmp-advanced-marker></gmp-advanced-marker>
</gmp-map>
<gmp-map center="47.759737, -122.250632" zoom="16" map-id="DEMO_MAP_ID">
  <div class="widget-container" slot="control-inline-start-block-start">
    <gmp-place-details>
      <gmp-place-details-place-request place="ChIJC8HakaIRkFQRiOgkgdHmqkk"></gmp-place-details-place-request>
      <gmp-place-all-content></gmp-place-all-content>
    </gmp-place-details>
  </div>
  <gmp-advanced-marker></gmp-advanced-marker>
</gmp-map>

Định cấu hình nội dung

Bạn có thể kiểm soát nội dung cụ thể về địa điểm mà phần tử gmp-place-details hiển thị bằng cách sử dụng phần tử gmp-place-content-config lồng nhau để chọn và định cấu hình thông tin chi tiết về địa điểm, như trong ví dụ này:

<gmp-map center="47.759737, -122.250632" zoom="16" map-id="DEMO_MAP_ID">
  <div class="widget-container" slot="control-inline-start-block-start">
    <gmp-place-details>
      <gmp-place-details-place-request place="ChIJC8HakaIRkFQRiOgkgdHmqkk"></gmp-place-details-place-request>
      <gmp-place-content-config>
        <gmp-place-address></gmp-place-address>
        <gmp-place-rating></gmp-place-rating>
        <gmp-place-type></gmp-place-type>
        <gmp-place-price></gmp-place-price>
        <gmp-place-accessible-entrance-icon></gmp-place-accessible-entrance-icon>
        <gmp-place-opening-hours></gmp-place-opening-hours>
        <gmp-place-website></gmp-place-website>
        <gmp-place-phone-number></gmp-place-phone-number>
        <gmp-place-summary></gmp-place-summary>
        <gmp-place-type-specific-highlights></gmp-place-type-specific-highlights>
        <gmp-place-reviews></gmp-place-reviews>
        <gmp-place-feature-list></gmp-place-feature-list>
        <gmp-place-media
          lightbox-preferred
          ></gmp-place-media>
          <gmp-place-attribution light-scheme-color="gray" dark-scheme-color="white"></gmp-place-attribution>
      </gmp-place-content-config>
    </gmp-place-details>
  </div>
  <gmp-advanced-marker></gmp-advanced-marker>
</gmp-map>

Bản thân phần tử gmp-place-content-config chứa một số phần tử nội dung con và mỗi phần tử chọn một chi tiết tương ứng về địa điểm để hiển thị: PlaceAddressElement chọn địa chỉ của địa điểm, PlacePriceElement chọn mức giá của địa điểm, v.v. Thứ tự của các phần tử con không liên quan, vì các chi tiết được chọn luôn được hiển thị theo một thứ tự cố định được xác định trước.

Bạn có thể định cấu hình thêm một số phần tử trong số này bằng cách sử dụng các thuộc tính dành riêng cho nội dung:

  • Phần tử gmp-place-media được dùng để hiển thị một bức ảnh duy nhất và có thuộc tính lightbox-preferred mở bức ảnh trong hộp đèn khi được nhấp vào. Theo mặc định, hộp đèn bị tắt.
  • Phần tử gmp-place-attribution được dùng để hiển thị nguồn của bức ảnh. Các thuộc tính light-scheme-colordark-scheme-color được dùng để đặt màu cho văn bản ghi công ở chế độ sáng và tối.
Xem tài liệu tham khảo PlaceContentConfigElement để biết thêm thông tin về tất cả các phần tử nội dung được hỗ trợ.

Để đơn giản, bạn có thể thay thế phần tử gmp-place-content-config bằng gmp-place-all-content để hiện tất cả thông tin chi tiết có trong phần tử Chi tiết về địa điểm hoặc bằng gmp-place-standard-content để hiển thị cấu hình tiêu chuẩn.

Định cấu hình giao diện

Phạm vi chiều rộng đề xuất cho phần tử gmp-place-details là 250px – 400px. Chiều rộng nhỏ hơn 250 px có thể không hiển thị đúng cách. Đặt chiều cao cho phù hợp với ứng dụng của bạn. Phần tử Chi tiết về địa điểm được thiết kế để cuộn trong không gian được phân bổ khi cần.

Phần tử gmp-place-details cũng hỗ trợ nhiều thuộc tính CSS tuỳ chỉnh để định cấu hình màu sắc và phông chữ của phần tử. Hãy xem phần Tuỳ chỉnh giao diện người dùng Places Kit để biết thêm thông tin chi tiết.

Xem ví dụ đầy đủ về mã

JavaScript

// Use querySelector to select elements for interaction.
const map = document.querySelector('gmp-map');
const placeDetails = document.querySelector('gmp-place-details');
const placeDetailsRequest = document.querySelector('gmp-place-details-place-request');
const marker = document.querySelector('gmp-advanced-marker');
let center = { lat: 47.759737, lng: -122.250632 };
async function initMap() {
    // Request needed libraries.
    await google.maps.importLibrary("maps");
    await google.maps.importLibrary("marker");
    await google.maps.importLibrary("places");
    // Hide the map type control.
    map.innerMap.setOptions({ mapTypeControl: false });
    // Function to update map and marker based on place details
    const updateMapAndMarker = () => {
        if (placeDetails.place && placeDetails.place.location) {
            let adjustedCenter = offsetLatLngRight(placeDetails.place.location, -0.005);
            map.innerMap.panTo(adjustedCenter);
            map.innerMap.setZoom(16); // Set zoom after panning if needed
            marker.position = placeDetails.place.location;
            marker.collisionBehavior = google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL;
            marker.style.display = 'block';
        }
    };
    // Set up map once widget is loaded.
    placeDetails.addEventListener('gmp-load', (event) => {
        updateMapAndMarker();
    });
    // Add an event listener to handle clicks.
    map.innerMap.addListener('click', async (event) => {
        marker.position = null;
        event.stop();
        if (event.placeId) {
            // Fire when the user clicks a POI.
            placeDetailsRequest.place = event.placeId;
            updateMapAndMarker();
        }
        else {
            // Fire when the user clicks the map (not on a POI).
            console.log('No place was selected.');
            marker.style.display = 'none';
        }
    });
}
// Helper function to offset marker placement for better visual appearance.
function offsetLatLngRight(latLng, longitudeOffset) {
    const newLng = latLng.lng() + longitudeOffset;
    return new google.maps.LatLng(latLng.lat(), newLng);
}
initMap();

CSS

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    display: flex; /* Use flexbox for layout */
    justify-content: center; /* Center the content horizontally */
    align-items: flex-start; /* Align items to the top */
    width: 100%
}

h1 {
  font-size: 16px;
  text-align: center;
}

gmp-map {
  height: 500px;
}

gmp-place-details {
  border-radius: 0px;
  margin: 20px;
  width: 400px;
  height: 500px;
  margin-top: 0px;
}

gmp-advanced-marker {
    display: none;
}

.widget-container {
  min-width: 400px;
  overflow-y: none;
  overflow-x: none;
}

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Click on the map to view place details</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <gmp-map center="47.759737, -122.250632" zoom="16" map-id="DEMO_MAP_ID">
        <gmp-advanced-marker></gmp-advanced-marker>
    </gmp-map>
    <div class="widget-container" slot="control-inline-start-block-start">
      <gmp-place-details>
        <gmp-place-details-place-request place="ChIJC8HakaIRkFQRiOgkgdHmqkk"></gmp-place-details-place-request>
        <gmp-place-all-content></gmp-place-all-content> 
      </gmp-place-details>
    </div>
    <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>
  </body>
</html>

Phần tử thu gọn của Thông tin chi tiết về địa điểm

Nhấp vào một điểm đánh dấu trên bản đồ để xem thông tin chi tiết về địa điểm trong một Phần tử nhỏ gọn về thông tin chi tiết về địa điểm.

PlaceDetailsCompactElement hiển thị thông tin chi tiết về một địa điểm đã chọn bằng cách sử dụng không gian tối thiểu. Điều này có thể hữu ích trong một cửa sổ thông tin làm nổi bật một địa điểm trên bản đồ, trong một trải nghiệm mạng xã hội như chia sẻ vị trí trong cuộc trò chuyện, dưới dạng đề xuất để chọn vị trí hiện tại của bạn hoặc trong một bài viết về nội dung nghe nhìn để tham chiếu địa điểm trên Google Maps.PlaceDetailsCompactElement có thể hiển thị tên, địa chỉ, điểm xếp hạng, loại, giá, biểu tượng hỗ trợ tiếp cận, trạng thái mở cửa và một bức ảnh. Bạn có thể hiển thị theo chiều ngang hoặc chiều dọc, tuỳ theo lựa chọn của thuộc tính orientation.

Trong đoạn mã sau, gmp-place-details-compact được lồng trong một phần tử gmp-map, với orientation được đặt thành horizontal. Một thuộc tính bổ sung, truncation-preferred, sẽ cắt bớt một số nội dung nhất định để vừa với một dòng thay vì xuống dòng. Phần tử gmp-place-details-compact chứa một phần tử con là gmp-place-details-place-request để chọn địa điểm. Đây có thể là một đối tượng Địa điểm, một mã địa điểm hoặc tên tài nguyên của Địa điểm theo định dạng "places/{place_id}":

<gmp-map center="47.75972, -122.25094" zoom="19" map-id="DEMO_MAP_ID">
  <gmp-place-details-compact orientation = "horizontal" truncation-preferred slot="control-block-start-inline-center" >
    <gmp-place-details-place-request place = "ChIJC8HakaIRkFQRiOgkgdHmqkk"></gmp-place-details-place-request>
    <gmp-place-content-config>
        <gmp-place-media lightbox-preferred></gmp-place-media>
        <gmp-place-rating></gmp-place-rating>
        <gmp-place-type></gmp-place-type>
        <gmp-place-price></gmp-place-price>
        <gmp-place-accessible-entrance-icon></gmp-place-accessible-entrance-icon>
        <gmp-place-open-now-status></gmp-place-open-now-status>
        <gmp-place-attribution light-scheme-color="gray" dark-scheme-color="white"></gmp-place-attribution>
    </gmp-place-content-config>
  </gmp-place-details-compact>
  <gmp-advanced-marker></gmp-advanced-marker>
</gmp-map>

Định cấu hình nội dung

Bạn có thể kiểm soát nội dung cụ thể về địa điểm mà phần tử gmp-place-details-compact hiển thị bằng cách sử dụng phần tử gmp-place-content-config lồng nhau để chọn và định cấu hình thông tin chi tiết về địa điểm. Bản thân phần tử gmp-place-content-config chứa một số phần tử nội dung con và mỗi phần tử sẽ chọn một thông tin chi tiết tương ứng về địa điểm để hiển thị. Thứ tự của các phần tử con không liên quan, vì các chi tiết đã chọn luôn được kết xuất theo một thứ tự cố định được xác định trước. Bạn có thể định cấu hình thêm một số phần tử trong số này bằng cách sử dụng các thuộc tính dành riêng cho nội dung.

Hãy xem tài liệu tham khảo PlaceContentConfigElement để biết thêm thông tin về tất cả các phần tử nội dung được hỗ trợ.

Để đơn giản, bạn có thể thay thế phần tử gmp-place-content-config bằng gmp-place-all-content để hiện tất cả thông tin chi tiết có trong phần tử Thông tin chi tiết về địa điểm ở dạng thu gọn hoặc bằng gmp-place-standard-content để hiện một cấu hình tiêu chuẩn.

Định cấu hình giao diện

Phạm vi chiều rộng đề xuất cho phần tử gmp-place-details-compact theo hướng dọc là 180 px – 300 px. Chiều rộng nhỏ hơn 160 px có thể không hiển thị chính xác. Đừng đặt chiều cao cố định.

Phạm vi chiều rộng đề xuất cho phần tử gmp-place-details-compact ở hướng ngang là 180 px – 500 px. Chiều rộng nhỏ hơn 160 px có thể không hiển thị chính xác. Ở chiều rộng dưới 350px, hình thu nhỏ sẽ không xuất hiện. Đừng đặt chiều cao cố định.

Phần tử gmp-place-details-compact cũng hỗ trợ nhiều thuộc tính CSS tuỳ chỉnh để định cấu hình màu sắc và phông chữ của phần tử. Hãy xem phần Tuỳ chỉnh giao diện người dùng Places Kit để biết thêm thông tin chi tiết.

Xem ví dụ đầy đủ về mã

Ví dụ này minh hoạ cách thêm PlaceDetailsCompactElement vào bản đồ theo phương thức lập trình bằng cách sử dụng AdvancedMarkerElement.

JavaScript

// Use querySelector to select elements for interaction.
const mapContainer = document.getElementById("map-container");
const placeDetails = document.querySelector("gmp-place-details-compact");
const placeDetailsRequest = document.querySelector("gmp-place-details-place-request");
let gMap;
let marker;
async function initMap() {
    const { PlaceDetailsCompactElement, PlaceDetailsPlaceRequestElement } = await google.maps.importLibrary("places");
    const { Map } = await google.maps.importLibrary("maps");
    const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
    gMap = new Map(mapContainer, { mapId: 'DEMO_MAP_ID' });
    marker = new AdvancedMarkerElement({ map: gMap });
    // Hide the map type control.
    gMap.setOptions({ mapTypeControl: false });
    // Set up map, marker, and infowindow once widget is loaded.
    placeDetails.style.visibility = 'visible';
    placeDetails.addEventListener('gmp-load', (event) => {
        console.log("placeDetails initialized!");
        updateMapAndMarker();
    });
    // Add an event listener to handle clicks.
    gMap.addListener("click", async (event) => {
        event.stop();
        // Fire when the user clicks on a POI.
        if (event.placeId) {
            console.log("clicked on POI");
            console.log(event.placeId);
            placeDetailsRequest.place = event.placeId;
            updateMapAndMarker();
        }
        else {
            // Fire when the user clicks the map (not on a POI).
            console.log('No place was selected.');
        }
        ;
    });
    // Function to update map, marker, and infowindow based on place details
    const updateMapAndMarker = () => {
        console.log("function called");
        if (placeDetails.place && placeDetails.place.location) {
            marker.gMap = null;
            let adjustedCenter = offsetLatLngRight(placeDetails.place.location, 0.002);
            gMap.panTo(adjustedCenter);
            gMap.setZoom(16); // Set zoom after panning if needed
            marker.content = placeDetails;
            marker.position = placeDetails.place.location;
        }
        else {
            console.log("else");
        }
    };
}
// Helper function to offset marker placement for better visual appearance.
function offsetLatLngRight(latLng, latitudeOffset) {
    const newLat = latLng.lat() + latitudeOffset;
    return new google.maps.LatLng(newLat, latLng.lng());
}
initMap();

CSS

html,
body {
  display: flex;
  width: 100%;
  height: 400px;
  margin: 0;
}

h1 {
  font-size: 16px;
  text-align: center;
}

#map-container {
    box-sizing: border-box;
    width: 100%;
}
gmp-place-details-compact {
  /* Sets the color for text and icons on the surface */
  /* Adapts automatically to the user's system light/dark mode preference */
  --gmp-mat-color-on-surface: light-dark(black, white);
  /* Sets the background color of the surface */
  /* Adapts automatically to the user's system light/dark mode preference */
  --gmp-mat-color-surface: light-dark(white, black);
  /* Defines the primary font stack used within the component */
  --gmp-mat-font-family: Google Sans Text, sans-serif;
  /* Defines the style for medium body text (e.g., address, descriptions) */
  --gmp-mat-font-body-medium: normal 400 0.875em/1.25em var(--gmp-mat-font-family, 'Google Sans Text');

  width: 360px;
  border: none;
  padding: 0;
  margin: 0;
  position: relative;
  transform: translate(0, calc(-20px));
}

/* This creates the pointer attached to the bottom of the element. */
gmp-place-details-compact::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 16px solid transparent;
  border-right: 16px solid transparent;
  border-top: 20px solid var(--gmp-mat-color-surface, light-dark(white, black));
}

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Click on the map to view place details</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id = "map-container"></div>
    <gmp-place-details-compact orientation="horizontal">
        <gmp-place-details-place-request place = ChIJn97JQNpC1moRIcJsVMEQLI8></gmp-place-details-place-request>
        <gmp-place-all-content></gmp-place-all-content>
    </gmp-place-details-compact>
    <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>  
  </body>
</html>