[英]React/Material-UI Slider/Leafet stopEventPropagation
我正在嘗試使用 react 創建帶有 material-ui 滑塊的傳單地圖控件。 出於某種原因,當我拖動滑塊時,它也會拖動地圖。 當我嘗試禁用控件上的單擊/鼠標移動傳播時,我無法再滑動滑塊。
https://codesandbox.io/s/ecstatic-taussig-iv8rj?file=/src/App.tsx
import * as React from "react";
import ReactDOM from "react-dom";
import L from "leaflet";
import { Slider } from "@material-ui/core";
function useMap(): [React.RefObject<HTMLDivElement>, L.Map | null] {
const mapRef = React.useRef<HTMLDivElement>(null);
const [map, setMap] = React.useState<L.Map>(null);
React.useEffect(() => {
if (!map && mapRef.current) {
const newMap = new L.Map(mapRef.current, {
center: [38.810820900566156, -95.54946899414064],
zoom: 5
});
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo(
newMap
);
setMap(newMap);
}
}, [map]);
return [mapRef, map];
}
function useLeafletWidget(
map: L.Map | null,
component: React.ReactElement | null
) {
const containerRef = React.useRef(document.createElement("div"));
React.useEffect(() => {
if (map) {
const Control = L.Control.extend({
onAdd() {
// L.DomEvent.disableClickPropagation(containerRef.current);
// L.DomEvent.on(containerRef.current, "mousemove", (event) => {
// event.stopPropagation();
// });
return containerRef.current;
}
});
const control = new Control({
position: "topleft"
});
map.addControl(control);
return () => {
map.removeControl(control);
};
}
}, [map]);
React.useEffect(() => {
if (component) {
const container = containerRef.current;
ReactDOM.render(component, container);
}
}, [component]);
React.useEffect(() => {
const container = containerRef.current;
return () => {
ReactDOM.unmountComponentAtNode(container);
};
}, [containerRef]);
}
function useSliderWidget(map: L.Map | null) {
const widget = React.useMemo(
() => (
<div style={{ backgroundColor: "white", padding: 10, width: 150 }}>
Slider: <Slider />
</div>
),
[]
);
useLeafletWidget(map, widget);
}
export const App: React.FC = () => {
const [mapRef, map] = useMap();
useSliderWidget(map);
return (
<>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossOrigin=""
/>
<div ref={mapRef} style={{ flexGrow: 1 }}></div>
</>
);
};
您可以在移動或鼠標懸停在滑塊上時添加map.dragging.disable()
和后來的map.dragging.enable()
。
根據 Falke 的回答,我實現了一個鈎子,用於在與地圖頂部的元素交互時禁用地圖拖動和滾動傳播。
import L from 'leaflet'
import { useEffect } from 'react'
import { useMap } from 'react-leaflet'
export const useDisablePropagationInMap = ({
ref,
}: {
ref: React.MutableRefObject<HTMLElement | null>
}) => {
const map = useMap()
useEffect(() => {
if (!ref.current) return
L.DomEvent.disableScrollPropagation(ref.current)
ref.current.onmouseenter = e => map.dragging.disable()
ref.current.onmouseleave = e => map.dragging.enable()
return () => {
map.dragging.enable()
}
}, [ref])
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.