reactjs 在MouseEnter,MouseLeave上更改React-Leaflet工具提示的z索引

li9yvcax  于 2023-10-17  发布在  React
关注(0)|答案(1)|浏览(95)

我使用react-leaflet和一些重叠的工具提示。当鼠标移到工具提示上时,工具提示的大小会发生变化。行为应该类似于https://travel.yandex.ru/hotels/search/?adults=2&bbox=37.41292205549375%2C55.63307944757846~37.796483919901604%2C55.85110332344529&checkinDate=2023-11-21&checkoutDate=2023-11-22&childrenAges=&geoId=213&lastSearchTimeMarker=1697537727502&navigationToken=0&oneNightChecked=false&searchPagePollingId=517ca65a3d0a582bae08c4c3f025a762-1-newsearch&selectedSortId=relevant-first或您可以在www.example.com上看到的行为booking.com
我试着将工具提示的位置链接到类,就像在Dynamically changing z-index for react-leaflet Tooltip帖子中一样,但找不到正确的条件。
这是我的代码

// Map code
import "leaflet/dist/leaflet.css";
import { IHotelResult } from "shared/types/IHotel";
import { LeafletMap } from "./leafletMap";
import { LocationMarker } from "./LocationMarker";
import { MapPopupContent } from "./mapPopupContent";
import { useSearchParams } from "react-router-dom";
import { useRef, useEffect } from "react";
import { Popup, Tooltip } from "react-leaflet";

export const MapBlock = ({
  hotels,
  idToOpen
}: {
  hotels: IHotelResult[], 
  idToOpen?: number
}) => {
  const mapRef = useRef<any>(null);
  const markerRef = useRef<any>(null);
  const [URLSearchParams] = useSearchParams();
  const long = Number(URLSearchParams.get('long'));
  const lat = Number(URLSearchParams.get('lat'));
// Show popup on hover on the left-side elements
  useEffect(() => {
    const map = mapRef.current;
    if (!map)  return;
   
    if (idToOpen !== undefined && markerRef.current) {
      markerRef.current.openPopup();
    }
  },[idToOpen]);
  
  return (
    <LeafletMap
      center={[lat, long]} 
      zoom={13} 
      scrollWheelZoom={true}
      ref={mapRef}
   >
      {hotels.length > 0 
        ? 
        <>
          {
            hotels.map((item, id) => {
              return (<LocationMarker
              initialCoords={[item.hotel.latitude, item.hotel.longitude]} 
              key={item.id}
              ref={id === idToOpen ? markerRef : null}
              price={item.price}
            >
              <>
                <MapPopupContent
                  img={item.hotel.hotel_information.photo}
                  name={item.hotel.name}
                  price={item.price}
                  stars={item.hotel.stars}
                />
              </>
            </LocationMarker>)})
          }
        </>
        : <></>
      }
    </LeafletMap>
  )
}
// marker code
import { LatLngExpression } from 'leaflet';
import { useState, ReactElement, forwardRef} from 'react';
import { useMapEvents, Marker, Popup, Tooltip } from 'react-leaflet';
import L from "leaflet";

interface ILocationMaker{
  initialCoords?: LatLngExpression | null;
  children: ReactElement;
  price: number;
};

export const LocationMarker = forwardRef(({
  initialCoords = null,
  children, 
  price,
}: ILocationMaker, ref: any) => {
  const [position, setPosition] = useState<LatLngExpression | null>(initialCoords);
  const map = useMapEvents ({
    click() {
      map.locate()
    },
    locationfound(e) {
      setPosition(e.latlng)
      map.flyTo(e.latlng, map.getZoom())
    },
  });

  const customIcon = new L.Icon({
    iconUrl: '/assets/img/location.svg',
    iconSize: [20, 20],
    iconAnchor: [10, 20]
  });
 

  return position === null 
  ? null 
  : (
      <Marker 
        position={position} 
        icon={customIcon} 
        ref={ref}
        eventHandlers={{
          mouseover: (evt) => console.log(evt.target), 
        }}
      >
        <Tooltip 
          direction="top" 
          opacity={1} 
          permanent
        >
          {`from ${price.toLocaleString()} $`}
        </Tooltip>
        <Popup>
          {children}
        </Popup>
      </Marker>
    )
});

请帮忙

sh7euo9m

sh7euo9m1#

您需要处理mouseover事件并相应地更新工具提示的内容和样式。

import { useState, ReactElement, forwardRef } from 'react';
import { useMapEvents, Marker, Popup, Tooltip } from 'react-leaflet';
import L from "leaflet";

interface ILocationMaker {
  initialCoords?: LatLngExpression | null;
  children: ReactElement;
  price: number;
};

export const LocationMarker = forwardRef(({
  initialCoords = null,
  children,
  price,
}: ILocationMaker, ref: any) => {
  const [position, setPosition] = useState<LatLngExpression | null>(initialCoords);
  const [tooltipContent, setTooltipContent] = useState(`from ${price.toLocaleString()} $`);
  const map = useMapEvents({
    click() {
      map.locate()
    },
    locationfound(e) {
      setPosition(e.latlng)
      map.flyTo(e.latlng, map.getZoom())
    },
  });

  const customIcon = new L.Icon({
    iconUrl: '/assets/img/location.svg',
    iconSize: [20, 20],
    iconAnchor: [10, 20]
  });

  const handleMouseOver = () => {
    setTooltipContent(`Price: ${price.toLocaleString()} $`);
  }

  const handleMouseOut = () => {
    setTooltipContent(`from ${price.toLocaleString()} $`);
  }

  return position === null
    ? null
    : (
      <Marker
        position={position}
        icon={customIcon}
        ref={ref}
      >
        <Tooltip
          direction="top"
          opacity={1}
          permanent
          onMouseOver={handleMouseOver}
          onMouseOut={handleMouseOut}
        >
          {tooltipContent}
        </Tooltip>
        <Popup>
          {children}
        </Popup>
      </Marker>
    )
});

相关问题