الأحداث

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ينشئ نموذج الأحداث في 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>
    <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>

    <!-- 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 للخرائط، فإنّ الطريقة 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 */ };