تصف هذه الصفحة أحداث واجهة المستخدم وأحداث الأخطاء التي يمكنك الاستماع إليها ومعالجتها آليًا.
أحداث واجهة المستخدم
تستند لغة JavaScript في المتصفّح إلى الأحداث، ما يعني أنّ لغة JavaScript تستجيب للتفاعلات من خلال إنشاء أحداث، ويتوقّع من البرنامج أن يستمع إلى الأحداث المهمة. هناك نوعان من الفعاليات:
- يتم نشر أحداث المستخدمين (مثل أحداث الماوس "النقر") من نموذج كائن المستند (DOM) إلى واجهة برمجة تطبيقات JavaScript للخرائط. تكون هذه الأحداث منفصلة ومختلفة عن أحداث DOM العادية.
- تعكس إشعارات تغيير حالة MVC التغييرات في عناصر واجهة برمجة تطبيقات JavaScript للخرائط
وتسمّى هذه الإشعارات باستخدام اصطلاح
property_changed
.
يصدِّر كل عنصر من عناصر واجهة برمجة التطبيقات JavaScript JavaScript عددًا من الأحداث المُعنوَنة.
وستسجّل البرامج المهتمة بأحداث معيّنة أدوات معالجة الأحداث في JavaScript لهذه الأحداث وتنفّذ رمزًا عند تلقّي هذه الأحداث من خلال طلب addListener()
لتسجيل معالجات الأحداث في الكائن.
سيعرِض لك النموذج التالي الأحداث التي يبدأها
google.maps.Map
أثناء تفاعلك مع الخريطة.
للحصول على قائمة كاملة بالأحداث، يمكنك الرجوع إلى مرجع واجهة برمجة التطبيقات JavaScript للخرائط. يتم إدراج الأحداث في قسم منفصل لكل عنصر يحتوي على أحداث.
أحداث واجهة المستخدم
تم تصميم بعض العناصر في Maps JavaScript API للاستجابة لأحداث المستخدم، مثل أحداث الماوس أو لوحة المفاتيح. على سبيل المثال، في ما يلي بعض أحداث
المستخدمين التي يمكن لعنصر google.maps.Marker
الاستماع إليها:
'click'
'dblclick'
'mouseup'
'mousedown'
'mouseover'
'mouseout'
للاطّلاع على القائمة الكاملة، راجِع فئة Marker. قد تبدو هذه الأحداث كأحداث DOM العادية، ولكنّها في الواقع جزء من Maps JavaScript API. وبما أنّ المتصفحات المختلفة تنفِّذ نماذج مختلفة لأحداث DOM، توفّر واجهة برمجة تطبيقات JavaScript JavaScript هذه الآليات للاستماع إلى أحداث DOM والاستجابة لها بدون الحاجة إلى التعامل مع الخصائص المتنوعة على مستوى المتصفحات. وتمرِّر هذه الأحداث أيضًا عادةً الوسيطات ضمن الحدث مع الإشارة إلى بعض حالات واجهة المستخدم (مثل موضع الماوس).
تغييرات حالة MVC
تحتوي كائنات MVC عادةً على حالة. عندما تتغيّر خاصية عنصر ما، تنشِّط واجهة Maps JavaScript API حدثًا تم فيه تغيير الموقع.
على سبيل المثال، ستطلق واجهة برمجة التطبيقات حدث 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 في "خرائط Google" تنشِّط هذه الأحداث الأخيرة بشكل مستقل، قد لا تُبلغ العلامة 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 في نظام أحداث Maps JavaScript 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
يُنشئ نموذج أحداث 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، يمكنك الاطّلاع على مرجع مستويات DOM في Mozilla DOM).
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 لـ "خرائط 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 */ };