التعامل مع أحداث الماوس

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

نظرة عامة

يمكنك إنشاء طبقة تفاعل مع أحداث mousemove وclick واستخدامها لعرض معلومات حول الحدود التي تم النقر عليها. وتشمل هذه المعلومات المعرّف والاسم المعروض ونوع الميزة. يعرض المثال التالي حدودًا لمستوى المنطقة الإدارية 2، ويحتوي على رمز معالجة الأحداث يحدّد المضلعات بناءً على تفاعل المستخدم (يغير mousemove سمك الحدود، وclick يظلل لون الخلفية ويتسبب في عرض نافذة معلومات).

تفعيل أحداث طبقة الميزات

اتّبِع الخطوات التالية لتفعيل الأحداث على طبقة عناصر:

  1. يمكنك تسجيل طبقة ميزة لإشعارات الأحداث من خلال استدعاء الوظيفة addListener() على طبقة الميزات لكل حدث تريد تسجيله. في هذا المثال، تحصل الخريطة أيضًا على مستمع.

    TypeScript

    // Add the feature layer.
    //@ts-ignore
    featureLayer = map.getFeatureLayer('ADMINISTRATIVE_AREA_LEVEL_2');
    
    // Add the event listeners for the feature layer.
    featureLayer.addListener('click', handleClick);
    featureLayer.addListener('mousemove', handleMouseMove);
    
    // Map event listener.
    map.addListener('mousemove', () => {
      // If the map gets a mousemove, that means there are no feature layers
      // with listeners registered under the mouse, so we clear the last
      // interacted feature ids.
      if (lastInteractedFeatureIds?.length) {
        lastInteractedFeatureIds = [];
        featureLayer.style = applyStyle;
      }
    });

    JavaScript

    // Add the feature layer.
    //@ts-ignore
    featureLayer = map.getFeatureLayer("ADMINISTRATIVE_AREA_LEVEL_2");
    // Add the event listeners for the feature layer.
    featureLayer.addListener("click", handleClick);
    featureLayer.addListener("mousemove", handleMouseMove);
    // Map event listener.
    map.addListener("mousemove", () => {
      // If the map gets a mousemove, that means there are no feature layers
      // with listeners registered under the mouse, so we clear the last
      // interacted feature ids.
      if (lastInteractedFeatureIds?.length) {
        lastInteractedFeatureIds = [];
        featureLayer.style = applyStyle;
      }
    });

  2. أضِف رمز معالج الأحداث لتصميم المضلّع المحدَّد استنادًا إلى نوع التفاعل.

    TypeScript

    function handleClick(/* MouseEvent */ e) {
      lastClickedFeatureIds = e.features.map(f => f.placeId);
      lastInteractedFeatureIds = [];
      featureLayer.style = applyStyle;
      createInfoWindow(e);
    }
    
    function handleMouseMove(/* MouseEvent */ e) {
      lastInteractedFeatureIds = e.features.map(f => f.placeId);
      featureLayer.style = applyStyle;
    }

    JavaScript

    function handleClick(/* MouseEvent */ e) {
      lastClickedFeatureIds = e.features.map((f) => f.placeId);
      lastInteractedFeatureIds = [];
      featureLayer.style = applyStyle;
      createInfoWindow(e);
    }
    
    function handleMouseMove(/* MouseEvent */ e) {
      lastInteractedFeatureIds = e.features.map((f) => f.placeId);
      featureLayer.style = applyStyle;
    }
    

  3. استخدام دالة نمط الميزة لتطبيق الأنماط. تطبق دالة نمط الميزة الموضحة هنا النمط بشكل مشروط بناءً على نوع التفاعل. وتم تحديد ثلاثة أنماط هنا: نمط لجعل الحد غامقًا في mousemove، ونمط آخر لتغيير الخلفية وعرض نافذة معلومات على click، ونمط تلقائي.

    TypeScript

    // Define styles.
    // Stroke and fill with minimum opacity value.
    const styleDefault = {
      strokeColor: '#810FCB',
      strokeOpacity: 1.0,
      strokeWeight: 2.0,
      fillColor: 'white',
      fillOpacity: 0.1,  // Polygons must be visible to receive events.
    };
    // Style for the clicked polygon.
    const styleClicked = {
      ...styleDefault,
      fillColor: '#810FCB',
      fillOpacity: 0.5,
    };
    // Style for polygon on mouse move.
    const styleMouseMove = {
      ...styleDefault,
      strokeWeight: 4.0,
    };
    
    // Apply styles using a feature style function.
    function applyStyle(/* FeatureStyleFunctionOptions */ params) {
      const placeId = params.feature.placeId;
      //@ts-ignore
      if (lastClickedFeatureIds.includes(placeId)) {
        return styleClicked;
      }
      //@ts-ignore
      if (lastInteractedFeatureIds.includes(placeId)) {
        return styleMouseMove;
      }
      return styleDefault;
    }

    JavaScript

    // Define styles.
    // Stroke and fill with minimum opacity value.
    const styleDefault = {
      strokeColor: "#810FCB",
      strokeOpacity: 1.0,
      strokeWeight: 2.0,
      fillColor: "white",
      fillOpacity: 0.1, // Polygons must be visible to receive events.
    };
    // Style for the clicked polygon.
    const styleClicked = {
      ...styleDefault,
      fillColor: "#810FCB",
      fillOpacity: 0.5,
    };
    // Style for polygon on mouse move.
    const styleMouseMove = {
      ...styleDefault,
      strokeWeight: 4.0,
    };
    
    // Apply styles using a feature style function.
    function applyStyle(/* FeatureStyleFunctionOptions */ params) {
      const placeId = params.feature.placeId;
    
      //@ts-ignore
      if (lastClickedFeatureIds.includes(placeId)) {
        return styleClicked;
      }
    
      //@ts-ignore
      if (lastInteractedFeatureIds.includes(placeId)) {
        return styleMouseMove;
      }
      return styleDefault;
    }
    

إكمال نموذج الرمز البرمجي

TypeScript

let map: google.maps.Map;
let featureLayer;
let infoWindow;
let lastInteractedFeatureIds = [];
let lastClickedFeatureIds = [];

function handleClick(/* MouseEvent */ e) {
  lastClickedFeatureIds = e.features.map(f => f.placeId);
  lastInteractedFeatureIds = [];
  featureLayer.style = applyStyle;
  createInfoWindow(e);
}

function handleMouseMove(/* MouseEvent */ e) {
  lastInteractedFeatureIds = e.features.map(f => f.placeId);
  featureLayer.style = applyStyle;
}

async function initMap() {
  // Request needed libraries.
  const { Map, InfoWindow } = await google.maps.importLibrary('maps') as google.maps.MapsLibrary;

  map = new Map(document.getElementById('map') as HTMLElement, {
    center: {lat: 39.23, lng: -105.73},
    zoom: 8,
    // In the cloud console, configure your Map ID with a style that enables the
    // 'Administrative Area Level 2' Data Driven Styling type.
    mapId: 'a3efe1c035bad51b', // Substitute your own map ID.
    mapTypeControl: false,
  });

  // Add the feature layer.
  //@ts-ignore
  featureLayer = map.getFeatureLayer('ADMINISTRATIVE_AREA_LEVEL_2');

  // Add the event listeners for the feature layer.
  featureLayer.addListener('click', handleClick);
  featureLayer.addListener('mousemove', handleMouseMove);

  // Map event listener.
  map.addListener('mousemove', () => {
    // If the map gets a mousemove, that means there are no feature layers
    // with listeners registered under the mouse, so we clear the last
    // interacted feature ids.
    if (lastInteractedFeatureIds?.length) {
      lastInteractedFeatureIds = [];
      featureLayer.style = applyStyle;
    }
  });

  // Create the infowindow.
  infoWindow = new InfoWindow({});
  // Apply style on load, to enable clicking.
  featureLayer.style = applyStyle;
}

// Helper function for the infowindow.
async function createInfoWindow(event) {
  let feature = event.features[0];
  if (!feature.placeId) return;

  // Update the infowindow.
  const place = await feature.fetchPlace();
  let content =
      '<span style="font-size:small">Display name: ' + place.displayName +
      '<br/> Place ID: ' + feature.placeId +
      '<br/> Feature type: ' + feature.featureType + '</span>';

  updateInfoWindow(content, event.latLng);
}

// Define styles.
// Stroke and fill with minimum opacity value.
const styleDefault = {
  strokeColor: '#810FCB',
  strokeOpacity: 1.0,
  strokeWeight: 2.0,
  fillColor: 'white',
  fillOpacity: 0.1,  // Polygons must be visible to receive events.
};
// Style for the clicked polygon.
const styleClicked = {
  ...styleDefault,
  fillColor: '#810FCB',
  fillOpacity: 0.5,
};
// Style for polygon on mouse move.
const styleMouseMove = {
  ...styleDefault,
  strokeWeight: 4.0,
};

// Apply styles using a feature style function.
function applyStyle(/* FeatureStyleFunctionOptions */ params) {
  const placeId = params.feature.placeId;
  //@ts-ignore
  if (lastClickedFeatureIds.includes(placeId)) {
    return styleClicked;
  }
  //@ts-ignore
  if (lastInteractedFeatureIds.includes(placeId)) {
    return styleMouseMove;
  }
  return styleDefault;
}

// Helper function to create an info window.
function updateInfoWindow(content, center) {
  infoWindow.setContent(content);
  infoWindow.setPosition(center);
  infoWindow.open({
    map,
    shouldFocus: false,
  });
}

initMap();

JavaScript

let map;
let featureLayer;
let infoWindow;
let lastInteractedFeatureIds = [];
let lastClickedFeatureIds = [];

function handleClick(/* MouseEvent */ e) {
  lastClickedFeatureIds = e.features.map((f) => f.placeId);
  lastInteractedFeatureIds = [];
  featureLayer.style = applyStyle;
  createInfoWindow(e);
}

function handleMouseMove(/* MouseEvent */ e) {
  lastInteractedFeatureIds = e.features.map((f) => f.placeId);
  featureLayer.style = applyStyle;
}

async function initMap() {
  // Request needed libraries.
  const { Map, InfoWindow } = await google.maps.importLibrary("maps");

  map = new Map(document.getElementById("map"), {
    center: { lat: 39.23, lng: -105.73 },
    zoom: 8,
    // In the cloud console, configure your Map ID with a style that enables the
    // 'Administrative Area Level 2' Data Driven Styling type.
    mapId: "a3efe1c035bad51b", // Substitute your own map ID.
    mapTypeControl: false,
  });
  // Add the feature layer.
  //@ts-ignore
  featureLayer = map.getFeatureLayer("ADMINISTRATIVE_AREA_LEVEL_2");
  // Add the event listeners for the feature layer.
  featureLayer.addListener("click", handleClick);
  featureLayer.addListener("mousemove", handleMouseMove);
  // Map event listener.
  map.addListener("mousemove", () => {
    // If the map gets a mousemove, that means there are no feature layers
    // with listeners registered under the mouse, so we clear the last
    // interacted feature ids.
    if (lastInteractedFeatureIds?.length) {
      lastInteractedFeatureIds = [];
      featureLayer.style = applyStyle;
    }
  });
  // Create the infowindow.
  infoWindow = new InfoWindow({});
  // Apply style on load, to enable clicking.
  featureLayer.style = applyStyle;
}

// Helper function for the infowindow.
async function createInfoWindow(event) {
  let feature = event.features[0];

  if (!feature.placeId) return;

  // Update the infowindow.
  const place = await feature.fetchPlace();
  let content =
    '<span style="font-size:small">Display name: ' +
    place.displayName +
    "<br/> Place ID: " +
    feature.placeId +
    "<br/> Feature type: " +
    feature.featureType +
    "</span>";

  updateInfoWindow(content, event.latLng);
}

// Define styles.
// Stroke and fill with minimum opacity value.
const styleDefault = {
  strokeColor: "#810FCB",
  strokeOpacity: 1.0,
  strokeWeight: 2.0,
  fillColor: "white",
  fillOpacity: 0.1, // Polygons must be visible to receive events.
};
// Style for the clicked polygon.
const styleClicked = {
  ...styleDefault,
  fillColor: "#810FCB",
  fillOpacity: 0.5,
};
// Style for polygon on mouse move.
const styleMouseMove = {
  ...styleDefault,
  strokeWeight: 4.0,
};

// Apply styles using a feature style function.
function applyStyle(/* FeatureStyleFunctionOptions */ params) {
  const placeId = params.feature.placeId;

  //@ts-ignore
  if (lastClickedFeatureIds.includes(placeId)) {
    return styleClicked;
  }

  //@ts-ignore
  if (lastInteractedFeatureIds.includes(placeId)) {
    return styleMouseMove;
  }
  return styleDefault;
}

// Helper function to create an info window.
function updateInfoWindow(content, center) {
  infoWindow.setContent(content);
  infoWindow.setPosition(center);
  infoWindow.open({
    map,
    shouldFocus: false,
  });
}

initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Handle Region Boundary Click Event</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>

تجربة "عيّنة"

اطّلِع على مزيد من المعلومات عن الأحداث.