Удаление события не работает
Я пытаюсь написать свою собственную систему делегирования событий, и она прекрасно работает, за исключением того, что я не могу удалить событие, как только присоединяю его к элементу! Я рвал на себе волосы, пытаясь понять это. Любая помощь будет принята с благодарностью.
Код в ручке: 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 ответ
Вопрос с bind()
, он возвращает новую функцию.
Из документации
Метод bind() создает новую функцию, которой при вызове присваивается ключевое слово this с указанным значением, причем заданная последовательность аргументов предшествует предоставленным при вызове новой функции.
Так что каждый раз, когда вы звоните 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);
и найдите какой-нибудь другой умный способ передать ваши варианты и т. д.