在另一个内部添加EventListener时,RemoveEventListener不起作用

时间:2017-06-20 23:27:34

标签: javascript

我正在尝试使用Javascript做我自己的颜色选择器轮,我希望能够通过在滚轮内拖动一个小圆圈(其中带有“+”符号)或通过单击某处的某个位置来选择颜色轮子(没有拖动小圆圈,但是小圆圈必须转到那个位置)。此外,我希望能够在我按下滚轮上的某个位置后触摸小圆圈(当触发mousedown事件时),直到我释放鼠标按钮(mouseup)。

在这里:在这里看到我想要的视觉效果要容易得多:     https://jsfiddle.net/s1qesLp9/1/

如果您取消注释第78行,那么您可以看到问题所在。

问题在于,当我使用添加和删除eventListeners时(因为我想要完成上述所有操作,我使用mousedown,mousemove和mouseup)我得到的结果是,每个mousedown上的警报数量都会增加1轮子(我在这里只需要一个警报,独立于车轮上有多少mousedowns!)。我在想是否与文档对象有关或者删除eventListeners有什么问题,但我不确定。

以下是我遇到问题的部分:

document.getElementById('wheel').addEventListener('mousedown', function(e) {
    targetMove(e);
    document.addEventListener('mousemove', targetMove);
    document.addEventListener('mouseup', function() {
      document.removeEventListener('mousemove', targetMove);
      document.onmouseup = null;
      alert("Here is the problem: For every mousedown on the wheel, the 
      number of alerts is increased by 1 (I only want one alert here!)");
    });
}, false);

3 个答案:

答案 0 :(得分:0)

这是因为你在每次mousedown之后都会向mouseup添加一个新的监听器,并且永远不会删除它。您可以移动它执行命名函数并在添加之前调用remove。删除不存在的侦听器不会导致我所知的任何问题。

< - edit - >我应该提到,如果为每个动作设置标志,从逻辑角度来看这可能会更容易。所以在mousedown上你会移动目标并将mouseheld设置为true。然后在mousemove上,如果mouseheld移动目标。最后onmouseup,将mouseheld设置为false。< - edit - />

document.getElementById('wheel').addEventListener('mousedown', function(e) {
    targetMove(e);
    document.addEventListener('mousemove', targetMove);
    
    //This listener is getting added with every mousedown and is never removed
    document.addEventListener('mouseup', function() {
      document.removeEventListener('mousemove', targetMove);
      document.onmouseup = null;
      alert("Here is the problem: For every mousedown on the wheel, the 
      number of alerts is increased by 1 (I only want one alert here!)");
    });
}, false);

答案 1 :(得分:0)

mousedown事件的事件侦听器,正在每个mousedown上再次添加相同的事件侦听器。如果从回调函数中删除这些事件侦听器,并单独添加它们,则不会出现此问题。

document.getElementById('wheel').addEventListener('mousedown', function(e) {
    targetMove(e);  
}, false);

document.addEventListener('mousemove', targetMove);
document.addEventListener('mouseup', function() {
    document.removeEventListener('mousemove', targetMove);
    document.onmouseup = null;
    alert("Problem solved!  You are binding this event listener only once.");
  }); 

这是jsFiddle

答案 2 :(得分:0)

我已经解决了!

而不是这个:

document.addEventListener('mouseup', function() {
    document.removeEventListener('mousemove', targetMove);
    document.onmouseup = null;
    alert("Here is the problem: For every mousedown on the wheel, the number 
of alerts is increased by 1 (I only want one alert here!)");
});

我有这个:

document.onmouseup = function() {
    document.removeEventListener('mousemove', targetMove);
    document.onmouseup = null;
    alert("Problem is solved");
};

所以问题是在mouseup上使用addEventListener方法,而是替换为document.onmouseup提供一个函数。

感谢您提供帮助,无论如何!