removeEventListener从body无法正常工作

时间:2015-09-16 14:18:02

标签: javascript event-listener

我试图在调用函数后删除事件侦听器。但是" keyup"的事件监听器无论我尝试什么,都会依附于身体。代码有什么问题?

function displayImage() {
  //this is a simplified version of the code
  var outerFrame = document.createElement('div');

  outerFrame.className = 'popup-outer';

  document.body.appendChild(outerFrame);

  document.body.addEventListener('keyup', hideImage.bind(outerFrame), false);
}

function hideImage(e) {
    if (e.keyCode === 27) {
    // this doesn't work, it stays attached to the body element
    document.body.removeEventListener('keyup', hideImage, false);
    document.body.removeChild(this);
  }

  e.preventDefault();
}

1 个答案:

答案 0 :(得分:1)

这是因为技术上

hideImage.bind(outerFrame)

不同
hideImage

因为第一个返回函数hideImage的副本。

因此,当您尝试取消绑定hideImage时,事件管理器找不到它,因为它注册了它的副本,因此没有删除任何内容: - /。

编辑:

在你的情况下,我猜你别无选择,只能跟踪你的听众。我继续快速做到这一点,它应该解决你的问题。

    var listeners = {};

    function createDiv() {
      var outerFrame = document.createElement('div');
      outerFrame.className = 'popup-outer';
      return outerFrame;
    }

    function displayImage() {
      var div = createDiv();
      bindEvent(div);
      document.body.appendChild(div);
    }

    function bindEvent(el) {
        var handler = function(e) {
            hideImg.call(el, e);
        }
        listeners[el] = handler;
        document.body.addEventListener('keyup', handler, false);
    }

    function hideImg(e) {
        if (e.keyCode === 27) { 
            // listeners[this] refers to the "private" handler variable we created in the bindEvent function
            document.body.removeEventListener('keyup', listeners[this], false);
            delete listeners[this];
            document.body.removeChild(this);
        }
    }