หน้านี้อธิบายเหตุการณ์ในอินเทอร์เฟซผู้ใช้และเหตุการณ์ข้อผิดพลาดที่คุณฟังและจัดการแบบเป็นโปรแกรมได้
เหตุการณ์อินเทอร์เฟซผู้ใช้
JavaScript ภายในเบราว์เซอร์เป็นแบบขับเคลื่อนด้วยเหตุการณ์ ซึ่งหมายความว่า JavaScript จะตอบสนองการโต้ตอบด้วยการสร้างเหตุการณ์ และคาดหวังว่าโปรแกรมจะฟังเหตุการณ์ที่น่าสนใจ เหตุการณ์มี 2 ประเภท ได้แก่
- เหตุการณ์ของผู้ใช้ (เช่น เหตุการณ์ "คลิก") ของเมาส์จะเผยแพร่จาก DOM ไปยัง Maps JavaScript API เหตุการณ์เหล่านี้แยกต่างหากและแตกต่างจากเหตุการณ์ DOM มาตรฐาน
- การแจ้งเตือนการเปลี่ยนแปลงสถานะ MVC แสดงถึงการเปลี่ยนแปลงในออบเจ็กต์ Maps JavaScript API และตั้งชื่อตามรูปแบบ
property_changed
ออบเจ็กต์ Maps JavaScript API แต่ละรายการจะส่งออกเหตุการณ์ที่มีชื่อจํานวนหนึ่ง
โปรแกรมที่สนใจบางเหตุการณ์จะลงทะเบียน Listener เหตุการณ์ของ JavaScript สําหรับเหตุการณ์เหล่านั้น และเรียกใช้โค้ดเมื่อเหตุการณ์เหล่านั้นได้รับโดยการเรียก addListener()
เพื่อลงทะเบียนเครื่องจัดการเหตุการณ์ในออบเจ็กต์
ตัวอย่างด้านล่างจะแสดงให้เห็นว่าเหตุการณ์ที่ google.maps.Map
ทริกเกอร์มีอะไรบ้างเมื่อคุณโต้ตอบกับแผนที่
ดูรายการเหตุการณ์ทั้งหมดได้ในข้อมูลอ้างอิง Maps JavaScript API เหตุการณ์จะแสดงในส่วนแยกต่างหากสําหรับแต่ละออบเจ็กต์ที่มีเหตุการณ์
เหตุการณ์ UI
ออบเจ็กต์บางอย่างภายใน Maps JavaScript API ได้รับการออกแบบมาให้ตอบสนองต่อเหตุการณ์ของผู้ใช้ เช่น เหตุการณ์ที่เป็นเมาส์หรือแป้นพิมพ์ ตัวอย่างเช่น เหตุการณ์บางส่วนที่ผู้ใช้ออบเจ็กต์ google.maps.Marker
ฟังได้มีดังนี้
'click'
'dblclick'
'mouseup'
'mousedown'
'mouseover'
'mouseout'
ดูรายการทั้งหมดได้ที่ชั้นเรียนเครื่องหมาย เหตุการณ์เหล่านี้อาจดูเหมือนเหตุการณ์ DOM มาตรฐาน แต่จริงๆ แล้วเป็นส่วนหนึ่งของ Maps JavaScript API เนื่องจากเบราว์เซอร์ต่างๆ ใช้โมเดลเหตุการณ์ DOM ที่แตกต่างกันไป Maps JavaScript API มีกลไกเหล่านี้ให้รับฟังและตอบสนองต่อเหตุการณ์ DOM โดยไม่ต้องจัดการการทํางานข้ามเบราว์เซอร์แบบต่างๆ นอกจากนี้ เหตุการณ์เหล่านี้มักจะส่งอาร์กิวเมนต์ภายในเหตุการณ์เพื่อแจ้งสถานะ UI บางรายการ (เช่น ตําแหน่งเมาส์)
การเปลี่ยนแปลงสถานะ MVC
โดยทั่วไปออบเจ็กต์ MVC จะมีสถานะ เมื่อใดก็ตามที่พร็อพเพอร์ตี้ของออบเจ็กต์มีการเปลี่ยนแปลง Maps JavaScript API จะเริ่มทํางานเหตุการณ์ที่พร็อพเพอร์ตี้มีการเปลี่ยนแปลง
เช่น API จะทําให้เหตุการณ์ zoom_changed
เริ่มทํางานบนแผนที่เมื่อระดับการซูมของแผนที่มีการเปลี่ยนแปลง คุณสกัดกั้นการเปลี่ยนแปลงสถานะเหล่านี้ได้โดยเรียกใช้ addListener()
เพื่อลงทะเบียนเครื่องจัดการเหตุการณ์ในออบเจ็กต์ด้วย
เหตุการณ์ของผู้ใช้และการเปลี่ยนแปลงสถานะ MVC อาจดูคล้ายกัน แต่โดยทั่วไปแล้วคุณต้องการดําเนินการกับโค้ดที่แตกต่างกัน ตัวอย่างเช่น เหตุการณ์ MVC จะไม่ส่งอาร์กิวเมนต์ภายในเหตุการณ์ คุณต้องตรวจสอบพร็อพเพอร์ตี้ที่มีการเปลี่ยนแปลงในการเปลี่ยนแปลงสถานะ MVC โดยเรียกเมธอด getProperty
ที่เหมาะสมในออบเจ็กต์นั้น
การจัดการเหตุการณ์
ใช้เครื่องจัดการเหตุการณ์ addListener()
เพื่อลงทะเบียนการแจ้งเตือนกิจกรรม วิธีนี้จะต้องใช้เหตุการณ์เพื่อฟัง และมีฟังก์ชันที่จะเรียกใช้เมื่อเหตุการณ์ที่ระบุเกิดขึ้น
ตัวอย่าง: เหตุการณ์บนแผนที่และเครื่องหมาย
โค้ดต่อไปนี้จะรวมเหตุการณ์ผู้ใช้เข้ากับเหตุการณ์การเปลี่ยนแปลงสถานะ เราได้แนบเครื่องจัดการเหตุการณ์ไว้กับตัวทําเครื่องหมายที่ซูมแผนที่เมื่อคลิก เรายังเพิ่มเครื่องจัดการเหตุการณ์ลงในแผนที่สําหรับการเปลี่ยนแปลงพร็อพเพอร์ตี้ center
และเลื่อนแผนที่กลับไปที่เครื่องหมายหลังจากผ่านไป 3 วินาทีหลังจากได้รับเหตุการณ์ center_changed
ดังนี้
TypeScript
function initMap(): void { const myLatlng = { lat: -25.363, lng: 131.044 }; const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: myLatlng, } ); const marker = new google.maps.Marker({ 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.getPosition() as google.maps.LatLng); }, 3000); }); marker.addListener("click", () => { map.setZoom(8); map.setCenter(marker.getPosition() as google.maps.LatLng); }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const myLatlng = { lat: -25.363, lng: 131.044 }; const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: myLatlng, }); const marker = new google.maps.Marker({ 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.getPosition()); }, 3000); }); marker.addListener("click", () => { map.setZoom(8); map.setCenter(marker.getPosition()); }); } window.initMap = initMap;
ลองใช้ตัวอย่าง
เคล็ดลับ: หากคุณพยายามตรวจหาการเปลี่ยนแปลงในวิวพอร์ต ให้ใช้เหตุการณ์ bounds_changed
เฉพาะแทนที่จะใช้เหตุการณ์ zoom_changed
และ center_changed
ที่ทําให้เกิดคอมโพเนนต์ เนื่องจาก Maps JavaScript API เริ่มการทํางานของเหตุการณ์หลังเหล่านี้ได้อย่างอิสระ getBounds()
จึงอาจไม่รายงานผลลัพธ์ที่มีประโยชน์จนกว่าวิวพอร์ตจะเปลี่ยนที่เชื่อถือได้ หากต้องการ
getBounds()
หลังกิจกรรมดังกล่าว อย่าลืมฟังเหตุการณ์ bounds_changed
แทน
ตัวอย่าง: เหตุการณ์การแก้ไขรูปร่างและการลาก
เมื่อแก้ไขหรือลากรูปร่างแล้ว เหตุการณ์จะเริ่มทํางานเมื่อมีการดําเนินการเสร็จสมบูรณ์ ดูรายการเหตุการณ์และข้อมูลโค้ดบางส่วนได้ในรูปร่าง
ดูตัวอย่าง (rectangle-event.html)
การเข้าถึงอาร์กิวเมนต์ในเหตุการณ์ UI
เหตุการณ์ UI ภายใน Maps JavaScript API มักจะส่งอาร์กิวเมนต์เหตุการณ์ ซึ่ง Listener เหตุการณ์จะเข้าถึงได้ และสังเกตสถานะ UI เมื่อเกิดเหตุการณ์ ตัวอย่างเช่น เหตุการณ์ UI ของ 'click'
มักจะส่ง MouseEvent
ที่มีพร็อพเพอร์ตี้ latLng
ซึ่งระบุตําแหน่งที่คลิกบนแผนที่ โปรดทราบว่าลักษณะการทํางานนี้ไม่ซ้ํากันสําหรับเหตุการณ์ UI การเปลี่ยนแปลงสถานะ MVC จะไม่ส่งอาร์กิวเมนต์ในเหตุการณ์
คุณเข้าถึงอาร์กิวเมนต์ของเหตุการณ์ภายใน Listener เหตุการณ์ได้ในลักษณะเดียวกับที่เข้าถึงพร็อพเพอร์ตี้ของออบเจ็กต์ ตัวอย่างต่อไปนี้เพิ่ม Listener เหตุการณ์สําหรับแผนที่ และสร้างเครื่องหมายเมื่อผู้ใช้คลิกแผนที่ที่ตําแหน่งที่คลิกได้
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: { lat: -25.363882, lng: 131.044922 }, } ); map.addListener("click", (e) => { placeMarkerAndPanTo(e.latLng, map); }); } function placeMarkerAndPanTo(latLng: google.maps.LatLng, map: google.maps.Map) { new google.maps.Marker({ position: latLng, map: map, }); map.panTo(latLng); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: { lat: -25.363882, lng: 131.044922 }, }); map.addListener("click", (e) => { placeMarkerAndPanTo(e.latLng, map); }); } function placeMarkerAndPanTo(latLng, map) { new google.maps.Marker({ position: latLng, map: map, }); map.panTo(latLng); } window.initMap = initMap;
ลองใช้ตัวอย่าง
การใช้การปิดใน Listener เหตุการณ์
ขณะเรียกใช้ Listener เหตุการณ์ การทําให้ข้อมูลมีทั้งส่วนตัวและถาวรอยู่ในออบเจ็กต์มักจะมีประโยชน์ JavaScript ไม่รองรับข้อมูลอินสแตนซ์ "ส่วนตัว" แต่รองรับการปิดทําการซึ่งช่วยให้ฟังก์ชันภายในเข้าถึงตัวแปรภายนอกได้ การปิดจะมีประโยชน์ภายใน Listener เหตุการณ์เพื่อเข้าถึงตัวแปรที่ไม่ได้แนบตามปกติกับออบเจ็กต์ที่มีเหตุการณ์เกิดขึ้น
ตัวอย่างต่อไปนี้ปิดฟังก์ชัน Listener เหตุการณ์เพื่อกําหนดข้อความลับให้กับชุดเครื่องหมาย การคลิกที่แต่ละเครื่องหมายจะแสดงส่วนของข้อความที่เป็นความลับซึ่งไม่ได้อยู่ในเครื่องหมายนั้น
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: { lat: -25.363882, lng: 131.044922 }, } ); 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({ 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, secretMessage: string ) { const infowindow = new google.maps.InfoWindow({ content: secretMessage, }); marker.addListener("click", () => { infowindow.open(marker.get("map"), marker); }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: { lat: -25.363882, lng: 131.044922 }, }); 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({ 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.get("map"), marker); }); } window.initMap = initMap;
ลองใช้ตัวอย่าง
การรับและตั้งค่าพร็อพเพอร์ตี้ภายในตัวแฮนเดิลเหตุการณ์
ไม่มีเหตุการณ์การเปลี่ยนแปลงสถานะ MVC ในเหตุการณ์ของระบบ JavaScript API ที่ส่งผ่านอาร์กิวเมนต์เมื่อมีการทริกเกอร์เหตุการณ์ (เหตุการณ์ของผู้ใช้จะส่งผ่านอาร์กิวเมนต์ที่ตรวจสอบได้) หากต้องการตรวจสอบพร็อพเพอร์ตี้ในการเปลี่ยนสถานะ MVC คุณควรเรียกใช้เมธอด getProperty()
ที่เหมาะสมในออบเจ็กต์นั้นอย่างชัดเจน การตรวจสอบนี้จะดึงข้อมูลสถานะปัจจุบันของออบเจ็กต์ MVC เสมอ ซึ่งอาจไม่ใช่สถานะที่เหตุการณ์เริ่มทํางานเป็นครั้งแรก
หมายเหตุ: การตั้งค่าพร็อพเพอร์ตี้อย่างชัดแจ้งภายในเครื่องจัดการเหตุการณ์ที่ตอบสนองต่อการเปลี่ยนแปลงสถานะพร็อพเพอร์ตี้นั้นๆ อาจทําให้เกิดพฤติกรรมที่คาดการณ์ไม่ได้และ/หรือไม่พึงประสงค์ การตั้งค่าพร็อพเพอร์ตี้ดังกล่าวจะเรียกเหตุการณ์ใหม่ เช่น หากตั้งค่าพร็อพเพอร์ตี้ภายในตัวแฮนเดิลเหตุการณ์นี้เสมอ การวนซ้ําอาจวนซ้ําได้ไม่รู้จบ
ในตัวอย่างด้านล่าง เราตั้งค่าเครื่องจัดการเหตุการณ์เพื่อตอบสนองต่อเหตุการณ์การซูม โดยเปิดหน้าต่างข้อมูลที่แสดงระดับนั้น
TypeScript
function initMap(): void { 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()!); }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { 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()); }); } window.initMap = initMap;
ลองใช้ตัวอย่าง
การฟังเหตุการณ์ DOM
รูปแบบเหตุการณ์ Maps JavaScript API จะสร้างและจัดการเหตุการณ์ที่กําหนดเองของตนเอง อย่างไรก็ตาม DOM (แบบจําลองออบเจ็กต์เอกสาร) ภายในเบราว์เซอร์ยังสร้างและส่งเหตุการณ์ของตนเองตามโมเดลเหตุการณ์ของเบราว์เซอร์ที่เจาะจงที่ใช้งานอยู่ หากต้องการบันทึกและตอบกลับเหตุการณ์เหล่านี้ Maps JavaScript API จะใช้เมธอด addDomListener()
แบบคงที่เพื่อฟังและเชื่อมโยงกับเหตุการณ์ DOM
วิธีอํานวยความสะดวกนี้มีลายเซ็นดังที่แสดงด้านล่าง
addDomListener(instance:Object, eventName:string, handler:Function)
โดยที่ instance
อาจเป็นองค์ประกอบ DOM ใดก็ได้ที่เบราว์เซอร์รองรับ รวมถึง
- สมาชิกที่เรียงตามลําดับชั้นของ DOM เช่น
window
หรือdocument.body.myform
- องค์ประกอบที่มีชื่อ เช่น
document.getElementById("foo")
โปรดทราบว่า addDomListener()
จะส่งเหตุการณ์ที่ระบุไปยังเบราว์เซอร์ ซึ่งจะจัดการตามรูปแบบเหตุการณ์ DOM ของเบราว์เซอร์ แต่เบราว์เซอร์รุ่นใหม่เกือบทั้งหมดรองรับ DOM ระดับ 2 เป็นอย่างน้อย (ดูข้อมูลเพิ่มเติมเกี่ยวกับเหตุการณ์ระดับ DOM ได้ที่ข้อมูลอ้างอิงระดับ Mozilla DOM
TypeScript
function initMap(): void { 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!"); }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { 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!"); }); } window.initMap = initMap;
HTML
<html> <head> <title>Listening to DOM Events</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 with https://www.npmjs.com/package/@googlemaps/js-api-loader. --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly" defer ></script> </body> </html>
ลองใช้ตัวอย่าง
แม้ว่าโค้ดข้างต้นจะเป็นโค้ด Maps JavaScript API แต่เมธอด addDomListener()
เชื่อมโยงกับออบเจ็กต์ window
ของเบราว์เซอร์ และช่วยให้ API สื่อสารกับออบเจ็กต์ที่อยู่นอกโดเมนปกติของ API ได้
นํา Listener เหตุการณ์ออก
หากต้องการนํา Listener เหตุการณ์ออก จะต้องกําหนด Listener เหตุการณ์ให้กับตัวแปร จากนั้นเรียก removeListener()
ได้โดยส่งชื่อตัวแปรที่กําหนดให้กับผู้ฟัง
var listener1 = marker.addListener('click', aFunction); google.maps.event.removeListener(listener1);
หากต้องการนํา Listener ทั้งหมดออกจากอินสแตนซ์หนึ่งๆ ให้เรียก clearInstanceListeners()
โดยส่งชื่ออินสแตนซ์
var listener1 = marker.addListener('click', aFunction); var listener2 = marker.addListener('mouseover', bFunction); // Remove listener1 and listener2 from marker instance. google.maps.event.clearInstanceListeners(marker);
หากต้องการนํา Listener ทั้งหมดสําหรับประเภทเหตุการณ์ที่เฉพาะเจาะจงสําหรับอินสแตนซ์หนึ่งๆ ให้เรียก clearListeners()
โดยส่งผ่านชื่ออินสแตนซ์และชื่อเหตุการณ์
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');
ดูข้อมูลเพิ่มเติมได้ในเอกสารประกอบอ้างอิงสําหรับเนมสเปซ google.maps.event
ฟังข้อผิดพลาดในการตรวจสอบสิทธิ์
หากต้องการตรวจหาความล้มเหลวของการตรวจสอบสิทธิ์แบบเป็นโปรแกรม (เช่น การส่งบีคอนโดยอัตโนมัติ) คุณก็เตรียมฟังก์ชันเรียกกลับได้
หากมีการกําหนดฟังก์ชันส่วนกลางต่อไปนี้ ระบบจะเรียกใช้เมื่อการตรวจสอบสิทธิ์ไม่สําเร็จ
function gm_authFailure() { /* Code */ };