Как показать местоположение маркера на карте при наведении курсора мыши на элемент div, например AirBnb

#javascript #reactjs #google-maps #leaflet

#javascript #reactjs #google-карты #брошюра

Вопрос:

У меня есть страница в элементах левой части div, таких как изображение элемента, заголовок, его детали, адрес, например. И на правой стороне у меня есть карта (карта листовки), показывающая маркеры адреса, которые берутся из всех этих элементов левой стороны. Теперь я хочу отображать местоположение маркера на карте при наведении курсора мыши на левую информацию с его адресом. Вскоре вы можете увидеть живой пример в airbnb.com

Я использую листовку React для map и реагирую, как вы видите. Но данные еще не извлекаются из базы данных, это фиктивные данные. Адрес определяется с помощью координат lat и lng

введите описание изображения здесь

Bikes.js

 import { BIKES, BikeTypes, BikeSize } from '../../data'
const Bikes = () => {
    return <div className="bikes-page">
        <div>
            <hr className="bike-bottom-line" />
            <BikesList items={BIKES} />
        </div>
        <div className="bikes-map">
            <MapContainer style={{ height: '50rem' }} coords={BIKES} mapZoom={9} />
        </div>
    </div>
}

export default Bikes
  

MapContainer.js (Компонент, изготовленный с помощью react-листовки)

 const MapContainer = (props) => {
    const DEFAULT_LATITUDE = 40.500;
    const DEFUALT_LANGITUDE = 49.500;
    return (
        <Map style={props.mapStyle} center={[DEFAULT_LATITUDE, DEFUALT_LANGITUDE]} zoom={props.mapZoom || 7} >
            <TileLayer
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                attribution='amp;copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            />
            {
                props.coords ?
                    props.coords.map(mark => {
                        return <Marker
                            position={[mark.location.lat, mark.location.lng]}
                            icon={biker}
                            key={mark.id} >
                            <Popup className="popup">
                                <Link to={`/b/${mark.id}`} className="popup-container">
                                    <img src={mark.images[0]} alt={mark.title} />
                                    <div className="popup-container__title">
                                        <h3> {mark.title} </h3>
                                        {mark.size}" · {mark.price.first}azn/s
                                    </div>
                                </Link>
                            </Popup>
                        </Marker>
                    }) : null
            }

        </Map >
    )
}

export default MapContainer
  

BikesList.js (левая сторона — Список)

 const BikesList = (props) => {
    if (props.items.length === 0) {
        return <h2>Elan tapılmadı</h2>
    }

    return (
        <ul className="bikes-list">
            {props.items.map((bike) => (
                <BikeItem
                    key={bike.id}
                    id={bike.id}
                    image={bike.images[0]}
                    title={bike.title}
                    city={bike.city}
                    size={bike.size}
                    price={bike.price.first}
                    creator={bike.creator}
                    maxLength={24}
                />
            ))}
        </ul>
    )
}

export default BikesList
  

Ответ №1:

Я сам нашел решение. Это было просто 🙂 Вот оно:

Во-первых, в Bikes.js файл, я создал состояние isHovered и присвоил ему значение null по умолчанию. Затем создал функцию handleHoverMarker (id) с идентификатором, который получит его из идентификатора определенного наведенного элемента. В функции я изменил значение setIsHovered на этот отправленный идентификатор. Итак, затем я поделился isHovered и handleHoverMarker с реквизитами.

Bikes.js

 const [isHovered, setIsHovered] = useState(null)
const handleHoverMarker = (id) => {
        setIsHovered(id)
}
<div>
   <BikesList handleHoverMarker={handleHoverMarker} items={filteredDataState} />
</div>
<div className="bikes-map">
   <MapContainer isHovered={isHovered} style={{ height: '50rem' }} coords={BIKES} mapZoom={9} />
</div>
  

Во-вторых, реквизит handleHoverMarker отправляется компоненту BikeItem, который представляет каждый из элементов в списке.

BikesList.js

 <ul className="bikes-list">
            {props.items.map((bike) => (
                <BikeItem
                    key={bike.id}
                    id={bike.id}
                    image={bike.images[0]}
                    title={bike.title}
                    city={bike.city}
                    size={bike.size}
                    price={bike.price.first}
                    creator={bike.creator}
                    maxLength={24}
                    handleHoverMarker={props.handleHoverMarker}
                />
            ))}
</ul>
  

В BikeItem.js установите события наведения курсора мыши и передайте идентификатор с помощью функции handleHoverMarker(id). Таким образом, мы будем знать, какой элемент зависал с идентификатором.

Примечание: я не писал все коды в BikeItem.js только принял необходимое участие

BikeItem.js

 <li onMouseEnter={()=> props.handleHoverMarker(props.id):null} onMouseLeave={()=>props.handleHoverMarker(null):null} key={props.id}>
  

Итак, здесь мы возвращаемся к MapContainer, который покажет местоположение наведенного элемента

MapContainer.js

 {props.coords ?
   props.coords.map(mark => {
                return <Marker
                position={[mark.location.lat, mark.location.lng]}
                icon={biker}
                opacity={props.isHovered === mark.id ? .7 :1}
                key={mark.id} >
                   <Popup className="popup">
                     <Link to={`/b/${mark.id}`} className="popup container">
                       <div className="popup-container__title">
                          <h3> {mark.title}</h3>
                       </div>
                     </Link>
                </Popup>
               </Marker>
 }) : null}
  

Здесь я условно изменил значение непрозрачности с помощью props.isHovered, которое мы отправили из Bikes.js досье.

Примечание: я не смог изменить стиль маркера, потому что я не нашел способ из documentaton карты листовки. Итак, логика та же, вы можете сделать это и с Картами Google. Удачи 🙂