将鼠标悬停在外部元素上时反应 Leaflet 更改标记

React Leaflet change maker when hover over outside element

我正在使用 React 和 Leaflet-React。我有一张地图和一叠类似于 yelp 的卡片。当有人将鼠标悬停在代表该站点的卡片上时,我想更改地图标记。我有根据状态变化的地图标记。地图制作器上的每个钥匙都有一个与卡片钥匙相匹配的唯一钥匙。

import React, { useEffect, useState }  from "react";
import FetchSites from "../../data/FetchSites";
import L from "leaflet";
import { Link } from "react-router-dom";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";

const customOfflineMarker =  L.icon({
  iconUrl: process.env.PUBLIC_URL + "/media/img/mapmakers/static/offline.png",
  iconSize: [50, 50],
  iconAnchor: [25, 5],
});
const customGreenMarker =  L.icon({
    iconUrl: process.env.PUBLIC_URL + "/media/img/mapmakers/static/pin_static_green.png",
    iconSize: [50, 50],
    iconAnchor: [25, 5],
  });

  const customYellowMarker =  L.icon({
    iconUrl: process.env.PUBLIC_URL + "/media/img/mapmakers/static/pin_static_yellow.png",
    iconSize: [50, 50],
    iconAnchor: [25, 5],
  });

  const customRedMarker =  L.icon({
    iconUrl: process.env.PUBLIC_URL + "/media/img/mapmakers/static/pin_static_red.png",
    iconSize: [50, 50],
    iconAnchor: [25, 5],
  });

  const customPurpleMarker =  L.icon({
    iconUrl: process.env.PUBLIC_URL + "/media/img/mapmakers/static/pin_static_purple.png",
    iconSize: [50, 50],
    iconAnchor: [25, 5],
  });
const customSelectedMarker =  L.icon({
    iconUrl: process.env.PUBLIC_URL + "/media/img/mapmakers/static/pin_selected.png",
    iconSize: [50, 50],
    iconAnchor: [25, 5],
  });
function mapMaker(props) {
    return L.icon({
        iconUrl: process.env.PUBLIC_URL + "/media/img/mapmakers/static/offline.png",
        iconSize: [50, 50],
        iconAnchor: [25, 5],
      });
}



function Dashboard() {
  
  const [response, loading, hasError] = FetchSites("api/data");
  return (
    <div className="listing-map-wrapper">
      <div className="listing-main-wrapper">
        {loading ? (
          <div>Loading...</div>
        ) : hasError ? (
          <div>Error occured.</div>
        ) : (
          <div>test</div>
        )}

        {response.map((item) => (
          <>
            {item.siteTypeId} - {item.siteType.en}
            {item.sites.map((site) => (
              <div className="col-lg-4">
                <div className="card-item d-flex">
                  <div className="site-level"></div>
                  <div className="card-image">
                    {site.siteImage ? (
                      <img
                        className="card__img"
                        src={`data:image/png;base64,${site.siteImage}`}
                      />
                    ) : (
                      ""
                    )}
                  </div>
                  <div className="card-conent-wrap">
                    <h4 className="card-title">{site.siteName}</h4>
                    <h4 className="card-title">
                      {site.lat} - {site.long}
                    </h4>
                  </div>
                </div>
              </div>
            ))}
          </>
        ))}
      </div>

      <div className="listing-map">
        <MapContainer
          className="markercluster-map map"
          center={[39.73899, -104.99102]}
          zoom={12}
        >
          <TileLayer
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          />
          {response.map((item, i) => (
            <>
              {item.sites.map((site) => (
                <>
                
                  {site.parameters.map((parameter) => (
                      <>
                    <Marker
                      key={site.siteId}
                      position={[site.lat, site.long]}
                      icon={(() => {
                        switch (parameter.parameterStatusItemId) {
                          case 1:   return customGreenMarker;
                          case 2:   return customYellowMarker;
                          case 3:   return customRedMarker;
                          case 4:   return customPurpleMarker;
                          case 5:   return customPurpleMarker;
                          default:  return customOfflineMarker;
                        }
                      })()}
                    >
                      <Popup>
                        <div className="mapboxgl-popup mapboxgl-popup-anchor-top">
                          <div className="mapboxgl-popup-tip" />
                          <img
                            src={`data:image/png;base64,${site.siteImage}`}
                            alt={site.siteName}
                          />
                          <div className="acr-listing-popup-body">
                            <h5>
                              <Link to="#" title={site.siteName}>
                                {site.siteName}
                              </Link>
                            </h5>
                            <p>
                              <i className="fas fa-map-signs" />
                              {site.siteDescription}
                            </p>
                            <div className="location-popup-meta">
                              <span>
                                <i className="fas fa-bed" />
                                {site.siteDescription2}
                              </span>
                            </div>
                          </div>
                        </div>
                      </Popup>
                    </Marker>
                    </>
                  ))}
                </>
              ))}
            </>
          ))}
        </MapContainer>
      </div>
    </div>
  );
}

export default Dashboard;
'''

因此,您需要维护一个状态变量来确定卡片是否悬停在上面,并将卡片的 ID 保存在其中:

function Dashboard() {
  const [highlightedCard, setHighlightedCard] = useState()
  // your other code
}

您的卡片元素需要附加鼠标事件以确定用户何时将鼠标悬停在上方或何时离开:

// in the return statement ...

{response.map((item) => (
  <>
    {item.siteTypeId} - {item.siteType.en}
    {item.sites.map((site) => (
      <div 
        className="col-lg-4" // assuming this is your card container element...
        onMouseEnter={() => setHighlightedCard(site.siteId)}
        onMouseLeave={() => setHighlightedCard(null)}
      >

  // the rest of your code continues...

所以现在,在鼠标进入时,卡片的 ID 设置为状态,并在鼠标离开时设置回 null。现在在您的标记数组中,您可以使用该状态变量:

{site.parameters.map((parameter) => (
  <>
    <Marker
      key={site.siteId}
      position={[site.lat, site.long]}
      icon={(() => { 
        if (site.siteId === highlightedCard){ // use state variable here
          return specialHighlightedMarker     // or whatever
        } else {                              // customize this as needed
          switch (parameter.parameterStatusItemId) {
            case 1:   return customGreenMarker;
            case 2:   return customYellowMarker;
            case 3:   return customRedMarker;
            case 4:   return customPurpleMarker;
            case 5:   return customPurpleMarker;
            default:  return customOfflineMarker;
          }
        }
      })()}
    >

  // code continues

我没有对此进行测试,但正如@kboul 所说,如果您提供一个工作演示(codesandbox、codepen 等),我们可以更好地帮助您实现它。只看页面上的代码,这就是我的处理方式。