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