الأحداث

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 للخرائط الأحداث المخصّصة ويديرها. ومع ذلك، ينشئ نموذج كائن المستند (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، يُرجى الاطّلاع على مرجع مستويات 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 API لتطبيق "خرائط 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 */ };