الأحداث

اختيار النظام الأساسي: Android iOS JavaScript

توضّح هذه الصفحة أحداث واجهة المستخدم وأحداث الأخطاء التي يمكنك الاستماع إليها والتعامل معها آليًا.

أحداث واجهة المستخدم

تكون JavaScript داخل المتصفّح مستندة إلى الأحداث، ما يعني أنّه تستجيب JavaScript للتفاعلات من خلال إنشاء أحداث، وتتوقّع أن يستمع البرنامج إلى الأحداث المثيرة للاهتمام. هناك نوعان من الأحداث:

  • يتم نشر أحداث المستخدمين (مثل أحداث الماوس "النقر") من عنصر DOM إلى Maps JavaScript API. وهذه الأحداث منفصلة ومختلفة عن أحداث DOM العادية.
  • تعكس إشعارات تغيير حالة نموذج التفاعل بين العميل والخادم (MVC) التغييرات في عناصر واجهة برمجة التطبيقات JavaScript API في "خرائط Google" ويتم تسميتها باستخدام اصطلاح property_changed.

يصدِّر كل كائن من واجهة برمجة التطبيقات JavaScript API في "خرائط Google" عددًا من الأحداث المحدّدة. ستسجِّل البرامج المهتمة بأحداث معيّنة مُستمعي الأحداث في JavaScript لهذه الأحداث، وستنفِّذ الرمز عند تلقّي هذه الأحداث من خلال استدعاء addListener() لتسجيل معالجات الأحداث في العنصر.

سيوضّح لك العيّنة التالية الأحداث التي تسبّب فيها google.maps.Map أثناء تفاعلك مع الخريطة.

للاطّلاع على قائمة كاملة بالأحداث، يمكنك الرجوع إلى مرجع Maps JavaScript API. يتم إدراج الأحداث في قسم منفصل لكل عنصر يحتوي على أحداث.

أحداث واجهة المستخدم

تم تصميم بعض العناصر ضمن Maps JavaScript API للاستجابة لأحداث المستخدمين، مثل أحداث الماوس أو لوحة المفاتيح. على سبيل المثال، في ما يلي بعض أحداث المستخدم التي يمكن لعنصر google.maps.marker.AdvancedMarkerElement الاستماع إليها:

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

للحصول على القائمة الكاملة، راجِع فئة AdvancedMarkerElement. قد تبدو هذه الأحداث مثل أحداث DOM العادية، ولكنها في الواقع جزء من Maps JavaScript API. بما أنّ المتصفحات المختلفة تنفِّذ نماذج مختلفة لأحداث DOM، توفِّر واجهة برمجة التطبيقات Maps JavaScript API هذه الآليات لمراقبة أحداث DOM والاستجابة لها بدون الحاجة إلى التعامل مع الخصائص المختلفة على مستوى جميع المتصفحات. وعادةً ما تُرسِل هذه الأحداث أيضًا مَعلمات ضمن الحدث تشير إلى بعض حالات واجهة المستخدم (مثل موضع الماوس).

تغييرات حالة نموذج التفاعل بين العميل والخادم (MVC)

تحتوي عناصر MVC عادةً على حالة. كلما تغيّرت سمة كائن، ستُطلق واجهة برمجة التطبيقات JavaScript لـ "خرائط Google" حدثًا يشير إلى أنّ السمة تغيّرت. على سبيل المثال، ستُطلق واجهة برمجة التطبيقات حدث zoom_changed على خريطة عند تغيير مستوى التكبير في الخريطة. يمكنك اعتراض تغييرات الحالة هذه من خلال استدعاء addListener() لتسجيل معالجات الأحداث على الكائن أيضًا.

قد تبدو أحداث المستخدم وتغييرات حالة نموذج التفاعل بين العميل والعرض متشابهة، ولكنك تريد بشكل عام التعامل معها بشكل مختلف في الرمز البرمجي. على سبيل المثال، لا تُمرِّر أحداث MVC سوى دلاّلات ضمن الحدث. ستحتاج إلى فحص السمة التي تغيّرت عند تغيير حالة MVC من خلال استدعاء الأسلوب المناسب 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. ولأنّ واجهة برمجة التطبيقات JavaScript لـ "خرائط Google" تُطلق هذه الأحداث الأخيرة بشكل مستقل، قد لا يُبلغ getBounds() عن نتائج مفيدة إلا بعد تغيير إطار العرض بشكل رسمي. إذا أردت getBounds() بعد حدث مماثل، احرص على معالجة الحدث bounds_changed بدلاً من ذلك.

مثال: أحداث تعديل الشكل وسحبه

عند تعديل شكل أو سحبه، يتم تشغيل حدث عند اكتمال الإجراء. للحصول على قائمة بالأحداث وبعض مقتطفات الرموز، يُرجى الاطّلاع على الأشكال.

الاطّلاع على مثال (rectangle-event.html)

الوصول إلى الوسيطات في أحداث واجهة المستخدم

عادةً ما تُرسِل أحداث واجهة المستخدم ضمن واجهة برمجة التطبيقات Maps JavaScript API مَعلمة حدث، يمكن لمراقب الحدث الوصول إليها، مع الإشارة إلى حالة واجهة المستخدم عند وقوع الحدث. على سبيل المثال، يُرسِل حدث 'click' لواجهة المستخدم عادةً MouseEvent يحتوي على سمة latLng تشير إلى الموقع الجغرافي الذي تم النقر عليه على الخريطة. يُرجى العِلم أنّ هذا السلوك فريد لأحداث واجهة المستخدم ، ولا تُرسِل تغييرات حالة نموذج التحكم في العرض (MVC) الوسيطات في أحداثها.

يمكنك الوصول إلى مَعلمات الحدث ضمن مستمع للأحداث بالطريقة نفسها التي يمكنك بها الوصول إلى سمات العنصر. يضيف المثال التالي أداة معالجة حدث للخريطة، وينشئ علامة عندما ينقر المستخدم على الخريطة في الموقع الجغرافي الذي تم النقر عليه.

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 باستخدام بيانات النماذج "الخاصة"، ولكنها تسمح باستخدام العناصر المُغلقة التي تسمح للدوالّ الداخلية بالوصول إلى المتغيرات الخارجية. تكون الدوالّ المغلقة مفيدة في مستمعي الأحداث للوصول إلى المتغيّرات التي لا يتم عادةً إرفاقها بالكائنات التي تحدث فيها الأحداث.

يستخدم المثال التالي إغلاق دالة في مستمع الأحداث لتحديد رسالة سرية لمجموعة من العلامات. سيؤدي النقر على كل علامة إلى الكشف عن جزء من الرسالة السرية، والذي لا يتضمّنه العلامة نفسها.

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();
عرض مثال

تجربة عيّنة

الحصول على الخصائص وضبطها ضمن معالِجات الأحداث

لا يُرسِل أيّ من أحداث تغيير حالة نموذج التحكم في العرض (MVC) في نظام أحداث واجهة برمجة التطبيقات JavaScript لـ "خرائط Google" سوى مناقشات عند بدء الحدث. (تُمرِّر أحداث المستخدِمين دلايلات يمكن فحصها). إذا كنت بحاجة إلى فحص خاصية عند تغيير حالة MVC، عليك استدعاء getProperty() الطريقة المناسبة على هذا الكائن بشكل صريح. سيسترجع هذا الفحص دائمًا الحالة الحالية لعنصر MVC ، والتي قد لا تكون الحالة عند بدء الحدث لأول مرة.

ملاحظة: قد يؤدي ضبط خاصيّة بشكل صريح ضمن معالج حدث يستجيب لتغيير حالة هذه الخاصيّة المحدّدة إلى ظهور سلوك غير متوقّع و/أو غير مرغوب فيه. سيؤدي ضبط خاصية كهذه إلى بدء حدث جديد، على سبيل المثال، وإذا كنت دائمًا تضبط خاصية ضمن معالِج الأحداث هذا، قد ينتهي بك الأمر بإنشاء حلقة لا نهائية.

في المثال أدناه، أعددنا معالِج أحداث للردّ على أحداث magnification (التكبير/التصغير) من خلال عرض نافذة معلومات تعرض هذا المستوى.

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

ينشئ نموذج أحداث 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 في المتصفّح، ومع ذلك، تتيح جميع المتصفّحات الحديثة تقريبًا استخدام المستوى 2 من DOM على الأقل. (لمزيد من المعلومات عن الأحداث على مستوى DOM، يُرجى الاطّلاع على مرجع مستويات Mozilla DOM.)

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 لـ "خرائط Google"، يتم ربط الأسلوب addDomListener() بكائن window للمتصفح ويسمح لواجهة برمجة التطبيقات بالتواصل مع الكائنات خارج نطاق واجهة برمجة التطبيقات العادي.

إزالة أدوات معالجة الأحداث

لإزالة أداة معالجة حدث معيّنة، يجب أن يكون قد تم إسنادها إلى متغيّر. يمكنك بعد ذلك استدعاء removeListener()، مع تمرير اسم المتغيّر الذي تمّ تعيين المستمع إليه.

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.

الاستماع إلى أخطاء المصادقة

إذا كنت تريد رصد تعذُّر المصادقة آليًا (على سبيل المثال، لإرسال إشارة تلقائيًا)، يمكنك إعداد وظيفة طلب معاودة الاتصال. في حال تحديد الدالة العامة التالية، سيتمّ استدعاؤها عند تعذُّر المصادقة. function gm_authFailure() { /* Code */ };