[英]How to disable an event listener in mapbox?
我正在尝试使用 React 上的 Mapbox 控制层上的事件侦听器。 map.off 应该可以解决这个问题,但它不会删除图层中的 onclick 事件。 https://docs.mapbox.com/mapbox-gl-js/api/map/#map#off
但是我做错了什么,所以我无法删除该事件。 这是我到目前为止所做的...
要添加我这样做的事件
map.on('click', 'building_footprints_click', addBuildingPopUp)
并尝试删除它我尝试过:
map.off('click', 'building_footprints_click', addBuildingPopUp);
map.off('click', 'building_footprints_click');
map.off('click', addBuildingPopUp);
但他们都没有工作。 我读到我必须发送到关闭事件的实例。 所以我试图:
let event = map.on('click', 'building_footprints_click', addBuildingPopUp)
以及与上面相同的三个关闭操作,但它们也不起作用
map.off('click', 'building_footprints_click', event);
map.off('click', 'building_footprints_click');
map.off('click', event);
还有监听器 function,我试过:
const addBuildingPopUp = (e) => {}
and
function addBuildingPopUp (e) {}
and
let addBuildingPopUp = function building (e) {}
这是一个基本的 Stackblitz,其中包含一个非工作示例 function https://stackblitz.com/edit/react-5maykf?file=src/App.js
我检查了您的 stackblitz 代码,并相应地使用评论更新了工作答案。 如果您对此有任何疑问,请告诉我
https://stackblitz.com/edit/react-mqjjkg?devtoolsheight=33&file=src/App.js
根据您的stackblitz ,我可以看到问题在于您正在尝试注销不再存在的 function。
对于 mapbox,您需要注册和注销相同的 function。 我的意思是map.on('mousemove', f1)
和map.off('mousemove', f1)
你需要确保 f1 保持不变。
让我解释一下,每当一个 react 组件渲染时,它都会在其主体内重新创建所有变量,除非它是 state 变量的一部分,因为 function addBuildingPopUp
是在每次渲染时创建的 mapboxgl 不会取消注册事件。
您需要做的唯一更改是确保addBuildingPopUp
保持不变,您应该在 React 组件外部定义。
如果您使用 React,只需将处理程序存储在 useRef 中,瞧,一切都会正常工作, 这是类似的情况和建议的解决方案
这是解决方案的代码:
const handleClickRef = useRef(handleClick)
handleClickRef.current = handleClick
map.on('mousedown', 'layer-id', handleClickRef.current)
map.off('mousedown', 'layer-id', handleClickRef.current)
您传递给 mapbox 事件侦听器的函数必须完全相同。 每次组件在 react 中渲染时,javascript 都会将 function(尽管它保持不变)识别为新声明的 function。 因此,mapbox 将“关闭”一个不存在事件的侦听器,因为它是一个从未存在过的 function。 要解决它,你必须使用 React “useCallback”。 它确保功能在组件存在的过程中保持不变
export default function MapListeners() {
const mode = useRecoilValue(interactivityMode);
const setModal = useSetRecoilState(modalState);
const removeListeners = () => {
cuMap.off("click", setAddBeaconModal);
};
const setAddBeaconModal = useCallback(
// useCallback ensures the functions stays identical
(e: mapboxgl.MapMouseEvent & mapboxgl.EventData) => {
// const coordinates = e.lngLat;
setModal({
key: AddBeaconModal.toString(),
body: {
component: AddBeaconModal,
props: { word: "irgendwas", title: "Irrr" },
},
title: "Add Beacon",
});
},
[]
);
const setMapListeners = () => {
removeListeners();
switch (mode) {
case "add":
cuMap.on("click", setAddBeaconModal);
break;
case "lock":
break;
default:
}
};
useEffect(setMapListeners, [mode]);
return null;
}
我已经在 React 中完成了。 我尝试了几天来做到这一点。 所以在我的情况下,我想删除一个点击监听器,它会添加一些自定义标记。 这是我的做法(用于测试):
Attributes in File
const map = useRef(null);
map.current.on('click', (event) => addMarkerOnClick(event));
setTimeout(() => {
console.log("Disabled")
map.current.off('click', (event) => addMarkerOnClick(event));
}, 5000)
以上是我最初的代码,它不会工作。
map.current.on('click', addMarkerOnClick);
setTimeout(() => {
console.log("Disabled")
map.current.off('click', addMarkerOnClick);
}, 5000)
这就是解决方案。
对于没有 React 的用户,我建议这样做:
// Attributes
let map = null
map.on('click', addMarkerOnClick);
setTimeout(() => {
console.log("Disabled")
map.off('click', addMarkerOnClick);
}, 5000)
我今天早上遇到了类似的问题,所以我会插话。 我最终采取的解决方案是将传递给 map.on 和 map.off 的 function 存储在带有空括号的 useCallback 挂钩中。 工作起来很有魅力!
我不知道你在写这个问题时是否打错了,但你写了
map.on('click', 'building_footprints_click', addBuildingPop**UP**);
map.off('click', 'building_footprints_click', addBuildingPop**Up**);
注意到 function 名称的大小写不同了吗?
这种语法是正确的,它是你应该使用的
如果问题是由于拼写错误,我建议使用 linter 来避免这种情况
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.