如何在addEventListener

时间:2018-08-16 10:52:12

标签: javascript addeventlistener

好的,这个问题在网络上已经有很多答案,我已经阅读了所有答案,但我认为其中没有一个适合我的情况。经过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。但是我不愿意这样做。

1 个答案:

答案 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,可能会有更简单的方法来解决我们可能建议的问题。