الأحداث

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

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

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

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

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

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

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

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

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

تم تصميم بعض الكائنات داخل واجهة برمجة تطبيقات JavaScript للخرائط للاستجابة لأحداث المستخدمين، مثل أحداث الماوس أو لوحة المفاتيح. على سبيل المثال، في ما يلي بعض أحداث المستخدم التي يمكن أن يستمع إليها الكائن google.maps.Marker:

  • 'click'
  • 'dblclick'
  • 'mouseup'
  • 'mousedown'
  • 'mouseover'
  • 'mouseout'

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

تغييرات حالة MVC

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

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

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

عرض مثال (rectangle-event.html)

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

تمرّر أحداث واجهة المستخدم في واجهة برمجة تطبيقات JavaScript للخرائط عادةً وسيطة حدث يمكن الوصول إليها بواسطة أداة معالجة الحدث، مع الإشارة إلى حالة واجهة المستخدم عند وقوعها. على سبيل المثال، عادةً ما يمرّر حدث واجهة المستخدم 'click' MouseEvent يحتوي على خاصية latLng تشير إلى الموقع الجغرافي الذي تم النقر عليه على الخريطة. لاحظ أن هذا السلوك فريد في أحداث واجهة المستخدم، ولا تؤدي تغييرات حالة MVC إلى تمرير الوسيطات في أحداثها.

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

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

تجربة النموذج

استخدام عمليات الإغلاق في أدوات معالجة الأحداث

عند تنفيذ أداة معالجة الحدث، من المفيد غالبًا إرفاق كل من البيانات الخاصة والمستمرة بكائن. لا يتيح JavaScript بيانات المثيلات "الخاصة"، ولكنه يتيح حالات الإغلاق التي تسمح بالوظائف الداخلية للوصول إلى المتغيّرات الخارجية. تفيد عمليات الإغلاق في أدوات معالجة الأحداث للوصول إلى المتغيرات التي لا يتم إرفاقها عادةً بالعناصر التي تحدث عليها الأحداث.

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

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 لـ Maps 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

ينشئ نموذج حدث واجهة برمجة تطبيقات JavaScript للخرائط أحداثه المخصّصة ويديرها. ومع ذلك، ينشئ DOM (نموذج كائن المستند) داخل المتصفّح أحداثه الخاصة ويرسلها وفقًا لنموذج حدث المتصفّح المستخدَم. وإذا كنت تريد تسجيل هذه الأحداث والاستجابة لها، توفّر واجهة برمجة تطبيقات JavaScript للخرائط طريقة addDomListener() الثابتة للاستماع إلى أحداث DOM وربطها.

وتشتمل طريقة تسهيل الاستخدام هذه على توقيع كما هو موضّح أدناه:

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

حيث instance يمكن أن يكون أي عنصر DOM متوافق مع المتصفح، بما في ذلك:

  • الأعضاء الهرميون في DOM مثل window أو document.body.myform
  • العناصر المسماة مثل document.getElementById("foo")

يُرجى العِلم بأنّ addDomListener() يمرِّر الحدث المُشار إليه إلى المتصفِّح، والذي يعالجه وفقًا لنموذج حدث DOM في المتصفّح، ومع ذلك، تدعم جميع المتصفحات الحديثة تقريبًا على الأقل المستوى 2 من عنصر DOM. (لمزيد من المعلومات حول الأحداث على مستوى DOM، يُرجى الاطّلاع على مرجع مستويات DOM في Mozilla.)

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.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
عرض مثال

تجربة النموذج

على الرغم من أن الرمز أعلاه هو رمز لواجهة برمجة تطبيقات JavaScript للخرائط، ترتبط طريقة 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 */ };