将鼠标悬停在外部元素上时反应 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='© <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 等),我们可以更好地帮助您实现它。只看页面上的代码,这就是我的处理方式。
我正在使用 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='© <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 等),我们可以更好地帮助您实现它。只看页面上的代码,这就是我的处理方式。