好的,这个问题在网络上已经有很多答案,我已经阅读了所有答案,但我认为其中没有一个适合我的情况。经过2个小时的尝试,我决定放弃并向这里的人问:
这是简化的示例:我有一个函数,该函数将通过单击按钮触发,我将其称为单击,并且它带有一个参数。在click函数内部,我需要使用addEventListener()
向窗口对象添加事件监听器。
我需要将事件传递给handleKeydown()
,因为我需要知道是否按下了Shift键(keycode == 16)
,并且需要将参数map
传递给{ {1}},因为我需要对此做些事情。之后,还有更多的事情要做,假设它具有在地图上绘制图片的功能
所以我写下面的代码:
handleKeydown()
一切正常,直到今天,我发现它还是一个大问题。
因为单击功能可以多次调用,所以我发现多个事件侦听器已附加到窗口对象上。这会对性能产生负面影响。
这个想法是将function click (map) { // can be called multiple times, so multiple listener are attached, not needed
this.addEventListener("keydown", function(e) {handleKeydown(e, map)}, false)
drawPictureOnMap(map);
}
function deletePictureOnMap() {
// user always call this function to delete the picture before they
// call the click() to draw a new one
// delete the picture on map
}
function handleKeydown(e, map) {
if (e.keyCode == 16) {
// do something to map, e. g.:
// map.getLayers()
}
}
附加到另一个功能上,这意味着删除地图上的图片。 因为,用户总是在绘制新图片之前将其删除。
问题是,我无法删除具有匿名功能的事件侦听器。但是,如果我想使用外部函数,就找不到将map参数传递给它的方法。
另一个想法是,将map参数设置为全局参数,因此无需将其传递给handleKeydown。但是我不愿意这样做。
答案 0 :(得分:0)
有几种解决方法。没有更多信息,我想到的是:为给定元素(WeakMap
维护处理程序的WeakMap
,这样,如果删除了该元素并删除了对该元素的所有引用,则地图条目会自动删除)。甚至IE11也支持WeakMap
(足够了)。
const elementClickHandlers = new WeakMap();
在该元素到处理程序的映射中,存储Map
键的处理程序中的map
。
然后在click
中使用这些地图:
function click (map) { // can be called multiple times, so multiple listener are attached, not needed
let handlers = elementClickHandlers.get(this);
if (!handlers) {
handlers = new Map();
elementClickHandlers.set(this, handlers);
}
let handler = handlers.get(map);
if (!handler) {
handler = function(e) {handleKeydown(e, map)};
handlers.set(map, handler);
}
this.addEventListener("keydown", handler, false)
drawPictureOnMap(map);
}
删除时,找到元素的处理程序并映射并删除它:
const handlers = elementClickHandlers.get(theElement);
if (handlers) {
const handler = handlers.get(map);
if (handler) {
handlers.delete(map);
someElement.removeEventListener("click", handler, false);
}
}
但是,如果您显示正确的MCVE,可能会有更简单的方法来解决我们可能建议的问题。