删除事件不起作用

时间:2015-12-07 23:36:49

标签: javascript javascript-events event-handling event-delegation

我正在尝试编写自己的事件委托系统,它工作得很好,除了我将它附加到元素后无法删除它!我一直在试图解决这个问题。任何帮助将不胜感激。

代码在笔中:http://codepen.io/anon/pen/BjyZyV?editors=101

以及下面:

标记

<ul id="parent">
  <li class="item">Lorum</li>
  <li class="item">Lorum</li>
  <li class="item">Lorum</li>
  <li class="item">Lorum</li>
  <li class="item">Lorum</li>
  <li class="item">Lorum</li>
  <li class="item">Lorum</li>
  <li class="item">Lorum</li>
  <li class="item">Lorum</li>
  <li class="item">Lorum</li>
</ul>

的JavaScript

Element.prototype.matches = Element.prototype.matches || Element.prototype.msMatchesSelector;

function isDescendant(parents, child) {
  for (var i = 0; i < parents.length; i++) {
    var node = child.parentNode;
    while (node !== null) {
      if (node === parents[i]) {
        return true;
      }
      node = node.parentNode;
    }
  }
  return false;
}

function eventCallback(e) {
  if (e.target && e.target.matches(this.options.selector)) {
    this.options.callback.call(this, e);
  } else if (isDescendant(this.parent.querySelectorAll(this.options.selector), e.target)) {
    this.options.callback.call(this, e);
  }
}

var MyEvent = {
  register: function register(options) {
    this.parent = document.querySelector(options.parentSelector);
    this.options = options;

    this.parent.addEventListener(options.event, eventCallback.bind(this), false);

    return this;
  },
  unregister: function unregister(options) {
    this.parent = document.querySelector(options.parentSelector);

    this.parent.removeEventListener(options.event, eventCallback, false);

    return this;
  }
};

myEvent = Object.create(MyEvent);

myEvent.register({
  event: 'click',
  parentSelector: '#parent',
  selector: '.item',
  callback: function(e) {
    alert('clicked!');
  }
});

myEvent.unregister({
  event: 'click',
  parentSelector: '#parent'
});

1 个答案:

答案 0 :(得分:1)

问题出在bind(),它会返回一个新功能 从文档

  

bind()方法创建一个新函数,当被调用时,它具有它   此关键字设置为提供的值,具有给定的序列   调用新函数时提供的任何参数。

因此,每当您致电bind时,您都会获得一个全新的功能,例如

this.parent.addEventListener(options.event, eventCallback.bind(this), false);

相同
var brandNewFunction = eventCallback.bind(this); // creates new function

this.parent.addEventListener(options.event, brandNewFunction, false);

所以你根本没有传递函数eventCallback,你传递了一个新函数,因此无法用

删除它
this.parent.removeEventListener(options.event, eventCallback, false);

因为你从未传递过eventCallback,并且removeEventListener的功能必须相同才能删除听众。
解决方案当然是这样称呼它

this.parent.addEventListener(options.event, eventCallback, false);

并找到一些其他聪明的方法来传递你的选择等。

相关问题