אירועים

בחירת פלטפורמה: Android iOS JavaScript

בדף הזה מתוארים האירועים בממשק המשתמש ואירועי השגיאה שניתן להאזין להם ולטפל בהם באופן פרוגרמטי.

אירועים בממשק המשתמש

JavaScript בדפדפן מבוסס על אירועים, כלומר JavaScript מגיב לאינטראקציות באמצעות יצירת אירועים, ומצפה תוכנית להאזנה לאירועים מעניינים. יש שני סוגים של אירועים:

  • אירועי משתמשים (כמו אירועי עכבר מסוג 'קליק') מופצים מה-DOM אל של Maps JavaScript API. האירועים האלה נפרדים ונפרדים מהאירועים האלה אירועי DOM רגילים.
  • התראות על שינויים במצב MVC משקפות שינויים ב-JavaScript API של מפות Google אובייקטים והם נקראים לפי המוסכמה property_changed.

כל אובייקט JavaScript של Maps API מייצא מספר אירועים בעלי שם. תוכניות שמתעניינות באירועים מסוימים ירשמו event listener של JavaScript עבור האירועים האלה ומריצים את הקוד כשהאירועים האלה מתקבלים נשלחת קריאה אל addListener() כדי לרשום גורמים מטפלים באירועים באובייקט.

בדוגמה הבאה אפשר לראות אילו אירועים מופעלים על ידי google.maps.Map בזמן האינטראקציה שלכם עם המפה.

לרשימה מלאה של האירועים, אפשר להיכנס חומר עזר בנושא JavaScript API של מפות Google. האירועים מפורטים בקטע נפרד לכל אובייקט שמכיל אירועים.

אירועים בממשק המשתמש

חלק מהאובייקטים ב-API JavaScript של מפות Google נועדו להגיב לאירועי משתמש כמו אירועים של עכבר או מקלדת. לדוגמה, אלה כמה מהמשתמשים אירועים שאובייקט google.maps.marker.AdvancedMarkerElement יכול להאזין להם:

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

לרשימה המלאה, אפשר לעיין AdvancedMarkerElement בכיתה. האירועים האלה עשויים להיראות כמו אירועי DOM רגילים, אבל הם בעצם חלק של Maps JavaScript API. כי דפדפנים שונים להטמיע מודלים שונים של אירועי DOM, ממשק API JavaScript של מפות Google מספק את המנגנונים האלה כדי להאזין לאירועי DOM ולהגיב להם בלי שיהיה צורך ולטפל בגורמים ספציפיים של ריבוי דפדפנים. האירועים האלה בדרך כלל גם מעבירים ארגומנטים באירוע מציין מצב מסוים בממשק המשתמש (למשל מיקום העכבר).

שינויים במצב MVC

אובייקטים מסוג MVC מכילים בדרך כלל מצב. בכל פעם שמאפיין אובייקט משתנה, Maps JavaScript API יפעיל אירוע שהנכס השתנה. לדוגמה, ה-API יפעיל אירוע zoom_changed על המפה בעקבות שינוי מרחק התצוגה של המפה. שינויים ברמה. אפשר להתקשר כדי להבחין בין שינויי המצב האלה addListener() כדי לרשום גורמים מטפלים באירועים גם על האובייקט.

אירועי משתמש ושינויים במצב MVC עשויים להיראות דומים, אבל באופן כללי להתייחס אליהם באופן שונה בקוד שלכם. לדוגמה, אירועי MVC לא עוברים ארגומנטים בתוך האירוע שלהם. כדאי לבדוק את הנכס במקרה של שינוי מצב MVC באמצעות קריאה ה-method getProperty באובייקט הזה.

טיפול באירועים

כדי להירשם לקבלת התראות על אירועים, יש להשתמש בaddListener() שמטפל באירועים. השיטה הזו לוקחת אירוע להאזנה, פונקציה לקריאה כשמתרחש האירוע שצוין.

דוגמה: אירועי מפה וסמנים

הקוד הבא משלבת אירועי משתמש עם אירועי שינוי מצב. אנחנו מצרפים הגורם המטפל באירועים לסמן שמגדיל את התצוגה במפה כשלוחצים עליה. אנחנו מוסיפים גם הגורם המטפל באירועים למפה עבור שינויים בנכס center ו להזיז את המפה חזרה אל הסמן לאחר 3 שניות לאחר קבלת אירוע 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();
להצגת דוגמה

כדאי לנסות דוגמה

טיפ: אם מנסים לזהות שינוי אזור התצוגה, יש להשתמש באירוע bounds_changed הספציפי במקום המרכיב zoom_changed ו- center_changed אירועים. מפני ש-Maps JavaScript API מפעיל את האירועים האחרים האלה באופן עצמאי, ייתכן שמערכת getBounds() לא תדווח על תוצאות מועילות עד שאזור התצוגה השתנה באופן רשמי. אם רוצים getBounds() אחרי אירוע כזה, חשוב להאזין ל אירוע אחד (bounds_changed) במקום זאת.

דוגמה: אירועים של עריכה וגרירה של צורה

כשמתבצעת עריכה או גרירה של צורה, אירוע מופעל אחרי שמסיימים פעולה. לרשימת האירועים ולחלק מקטעי הקוד: צורות.

תצוגה example (rectangle-event.html)

גישה לארגומנטים באירועים בממשק המשתמש

אירועים בממשק המשתמש של Maps JavaScript API בדרך כלל מעבירים ארגומנט event, שאליו ה-event listener יכול לגשת, תוך ציון מצב ממשק המשתמש כאשר התרחש אירוע. לדוגמה, אירוע 'click' בממשק המשתמש בדרך כלל עובר MouseEvent שמכיל מאפיין latLng, שמציין המיקום שעליו לוחצים במפה. חשוב לשים לב שההתנהגות הזו היא ייחודית לממשק המשתמש. אירועים; שינויים במצב MVC לא מעבירים ארגומנטים באירועים שלהם.

אפשר לגשת לארגומנטים של האירוע בתוך האזנה לאירועים באותה הדרך צריך לגשת למאפיינים של אובייקט. בדוגמה הבאה הוספת אירוע Listener למפה ויוצר סמן כשהמשתמש לוחץ על המפה בכתובת המיקום שעליו לחץ המשתמש.

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();
להצגת דוגמה

כדאי לנסות דוגמה

שימוש בחסימות כבישים במאזינים לאירועים

כשמפעילים האזנה לאירוע, לעיתים קרובות יש יתרון בשני המקרים נתונים פרטיים ועקביים המצורפים לאובייקט. JavaScript לא תמיכה "פרטי" אבל הם תומכים סגירות שמאפשרות לפונקציות פנימיות לגשת לחלק החיצוני משתנים. חסימות כבישים הן כלי שימושי למאזינים של אירועים שלא יכולים לגשת למשתנים בדרך כלל מצורפים לאובייקטים שבהם מתרחשים אירועים.

הדוגמה הבאה משתמשת בסגירת פונקציה ב-event listener כדי להקצות הודעה סודית לקבוצת סמנים. לחיצה על כל סמן חלק מההודעה הסודית, שלא נכלל לסמן עצמו.

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();
להצגת דוגמה

כדאי לנסות דוגמה

קבלה והגדרה של מאפיינים ברכיבי handler של אירועים

אף אחד מאירועי השינוי של מצב MVC ב-Maps JavaScript API לא עבר את מערכת האירועים ארגומנטים כשהאירוע מופעל. (אירועי משתמש כן להעביר ארגומנטים שניתן לבדוק.) אם אתם צריכים לבדוק נכס במקרה של שינוי מצב MVC, צריך לקרוא באופן מפורש ה-method getProperty() באובייקט הזה. הזה הבדיקה תמיד תאחזר את המצב הנוכחי של ה-MVC וייתכן שהוא לא המצב שבו האירוע הופעל לראשונה.

הערה: הגדרה מפורשת של נכס בתוך גורם לטיפול באירועים שמגיב לשינוי מצב של הגורם הספציפי הזה הנכס עלול לגרום להתנהגות בלתי צפויה או לא רצויה. ההגדרה נכס כזה יפעיל אירוע חדש, לדוגמה, ואם תמיד אם תגדירו מאפיין בתוך הגורם המטפל באירועים, ייתכן שבסופו של דבר תיצרו נכס לולאה אינסופית.

בדוגמה הבאה אנחנו מגדירים גורם שמטפל באירועים כדי להגיב עליו אירועי זום על ידי הצגת חלון מידע שמציג את הרמה הזאת.

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();
להצגת דוגמה

כדאי לנסות דוגמה

האזנה לאירועי DOM

מודל האירועים של JavaScript ב-Maps 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. רמות DOM של 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>
להצגת דוגמה

כדאי לנסות דוגמה

למרות שהקוד שלמעלה הוא קוד JavaScript API של מפות Google, ה-method addDomListener() מקשרת לאובייקט window של הדפדפן ומאפשר ל-API לתקשר עם אובייקטים מחוץ הדומיין הרגיל של ה-API.

הסרת פונקציות event listener

כדי להסיר אוזן ספציפי של אירוע, צריך להקצות אותו ל מותאם אישית. לאחר מכן אפשר להתקשר אל removeListener(), העברה של שם המשתנה שאליו הוקצה ה-listen.

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

google.maps.event.removeListener(listener1);

כדי להסיר את כל המאזינים ממופע מסוים, מפעילים 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);

כדי להסיר את כל המאזינים לסוג אירוע ספציפי של מופע ספציפי: קוראים לפונקציה 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 namespace.

האזנה לשגיאות אימות

אם רוצים לזהות באופן פרוגרמטי כשל באימות (לדוגמה כדי לשלוח איתות באופן אוטומטי) אפשר להכין פונקציית קריאה חוזרת. אם הפונקציה הגלובלית הבאה מוגדרת היא תיקרא כאשר האימות נכשל. function gm_authFailure() { /* Code */ };