【问题标题】:Cannot removing an event from my own event delegation system无法从我自己的事件委托系统中删除事件
【发布时间】:2015-12-07 23:36:49
【问题描述】:

我正在尝试编写自己的事件委托系统,它工作得很好,只是一旦我将事件附加到元素上就无法删除它!我一直在扯头发试图弄清楚这一点。任何帮助将不胜感激。

代码在笔中: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'
});

【问题讨论】:

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


    【解决方案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);
    

    并找到一些其他巧妙的方法来传递您的选项等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多