توضّح هذه الصفحة أحداث واجهة المستخدم وأحداث الخطأ التي يمكنك الاستماع إليها والتعامل معها آليًا.
أحداث واجهة المستخدم
إنّ JavaScript في المتصفّح يعتمد على الأحداث، ما يعني أنّ JavaScript يستجيب للتفاعلات من خلال إنشاء أحداث، ويتوقّع من البرنامج الاستماع إلى الأحداث المهمة. هناك نوعان من الأحداث:
- يتم نقل أحداث المستخدم (مثل أحداث الماوس "click") من نموذج المستند (DOM) إلى Maps JavaScript API. تكون هذه الأحداث منفصلة ومختلفة عن أحداث DOM العادية.
- تعكس إشعارات تغيير حالة MVC التغييرات في عناصر Maps JavaScript API، ويتم تسميتها باستخدام اصطلاح
property_changed.
يصدّر كل عنصر من عناصر Maps JavaScript API عددًا من الأحداث المسماة.
ستسجّل البرامج المهتمة بأحداث معيّنة برامج معالجة الأحداث في 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، توفّر واجهة برمجة تطبيقات JavaScript لخرائط Google هذه الآليات للاستماع إلى أحداث DOM والاستجابة لها بدون الحاجة إلى التعامل مع الخصائص المختلفة المتوافقة مع المتصفّحات المتعددة. وعادةً ما تمرِّر هذه الأحداث أيضًا وسيطات ضمن الحدث تشير إلى بعض حالات واجهة المستخدم (مثل موضع مؤشر الماوس).
تغييرات حالة MVC
تحتوي عناصر MVC عادةً على حالة. عندما تتغيّر سمة أحد العناصر، ستطلق "واجهة برمجة تطبيقات JavaScript للخرائط" حدثًا يشير إلى أنّ السمة قد تغيّرت.
على سبيل المثال، ستطلق واجهة برمجة التطبيقات الحدث zoom_changed على خريطة عند تغيير مستوى التكبير/التصغير في الخريطة. يمكنك اعتراض تغييرات الحالة هذه من خلال استدعاء
addListener() لتسجيل معالجات الأحداث على العنصر أيضًا.
قد تبدو أحداث المستخدم وتغييرات حالة MVC متشابهة، ولكن يجب التعامل معها بشكل مختلف في الرمز البرمجي. على سبيل المثال، لا تمرِّر أحداث MVC وسيطات ضمن الحدث. افحص السمة التي تم تغييرها عند تغيير حالة MVC من خلال استدعاء طريقة getProperty المناسبة على هذا العنصر.
التعامل مع الأحداث
للتسجيل في إشعارات الأحداث، استخدِم معالج الأحداث addListener(). تتلقّى هذه الطريقة حدثًا للاستماع إليه، ودالة يتم استدعاؤها عند وقوع الحدث المحدّد.
مثال: أحداث الخريطة والعلامة
يخلط الرمز التالي بين أحداث المستخدم وأحداث تغيير الحالة. يربط هذا المثال معالج أحداث بعلامة تؤدي إلى تكبير الخريطة عند النقر عليها. كما يرفق معالج أحداث بالخريطة
للتغييرات التي تطرأ على السمة center، ويحرّك الخريطة مجددًا إلى العلامة بعد 3 ثوانٍ من تلقّي الحدث center_changed.
TypeScript
async function initMap() { // Request needed libraries. (await google.maps.importLibrary('maps')) as google.maps.MapsLibrary; (await google.maps.importLibrary('marker')) as google.maps.MarkerLibrary; // Retrieve the map element. const mapElement = document.querySelector( 'gmp-map' ) as google.maps.MapElement; // Get the inner map from the map element. const innerMap = mapElement.innerMap; const center = mapElement.center; const marker = new google.maps.marker.AdvancedMarkerElement({ position: center, map: innerMap, title: 'Click to zoom', gmpClickable: true, }); innerMap.addListener('center_changed', () => { // 3 seconds after the center of the map has changed, // pan back to the marker. window.setTimeout(() => { innerMap.panTo(marker.position as google.maps.LatLng); }, 3000); }); // Zoom in when the marker is clicked. marker.addListener('gmp-click', () => { innerMap.setZoom(8); innerMap.setCenter(marker.position as google.maps.LatLng); }); } initMap();
JavaScript
async function initMap() { // Request needed libraries. (await google.maps.importLibrary('maps')); (await google.maps.importLibrary('marker')); // Retrieve the map element. const mapElement = document.querySelector('gmp-map'); // Get the inner map from the map element. const innerMap = mapElement.innerMap; const center = mapElement.center; const marker = new google.maps.marker.AdvancedMarkerElement({ position: center, map: innerMap, title: 'Click to zoom', gmpClickable: true, }); innerMap.addListener('center_changed', () => { // 3 seconds after the center of the map has changed, // pan back to the marker. window.setTimeout(() => { innerMap.panTo(marker.position); }, 3000); }); // Zoom in when the marker is clicked. marker.addListener('gmp-click', () => { innerMap.setZoom(8); innerMap.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. await google.maps.importLibrary("maps") as google.maps.MapsLibrary; await google.maps.importLibrary("marker") as google.maps.MarkerLibrary; const mapElement = document.querySelector('gmp-map') as google.maps.MapElement; const innerMap = mapElement.innerMap; innerMap.addListener("click", (e) => { placeMarkerAndPanTo(e.latLng, innerMap); }); } 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. await google.maps.importLibrary("maps"); await google.maps.importLibrary("marker"); const mapElement = document.querySelector('gmp-map'); const innerMap = mapElement.innerMap; innerMap.addListener("click", (e) => { placeMarkerAndPanTo(e.latLng, innerMap); }); } 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. (await google.maps.importLibrary('maps')) as google.maps.MapsLibrary; (await google.maps.importLibrary('marker')) as google.maps.MarkerLibrary; const mapElement = document.querySelector( 'gmp-map' ) as google.maps.MapElement; const innerMap = mapElement.innerMap; 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. innerMap.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: innerMap, }); 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('gmp-click', () => { infowindow.open(marker.map, marker); }); } initMap();
JavaScript
async function initMap() { // Request needed libraries. (await google.maps.importLibrary('maps')); (await google.maps.importLibrary('marker')); const mapElement = document.querySelector('gmp-map'); const innerMap = mapElement.innerMap; const bounds = { north: -25.363882, south: -31.203405, east: 131.044922, west: 125.244141, }; // Display the area between the location southWest and northEast. innerMap.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: innerMap, }); 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('gmp-click', () => { infowindow.open(marker.map, marker); }); } initMap();
تجربة عيّنة
الحصول على الخصائص وضبطها ضمن معالجات الأحداث
لا يمرّر أي من أحداث تغيير حالة MVC في نظام أحداث Maps 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();
تجربة عيّنة
إزالة أدوات معالجة الأحداث
لإزالة متتبِّع أحداث معيّن، يجب أن يكون قد تم تعيينه إلى مُتغيِّر. يمكنك بعد ذلك استدعاء 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 */ };
في TypeScript، قد يكون من الضروري إضافة الدالة إلى النطاق العام كما هو موضّح أدناه:
// Define the callback function. window.gm_authFailure = () => { console.error("Google Maps failed to authenticate."); /* Code */ }; // Add gm_authFailure to the global scope. declare global { interface Window { gm_authFailure?: () => void; } } export {};