2015-08-11 2 views
0

У меня есть специальный сценарий, описанный как можно в этой ручке: http://codepen.io/tuelsch/pen/rVRRNm?editors=101Удалить прослушиватель событий ванили JS

Эта статья (Adding and Removing Event Listeners with parameters) указала мне в правильном направлении, но имеет другую установку.

Мне нравится иметь пользовательский объект JS (фильм), который может добавлять и удалять обработчик событий в свой link свойство (элемент DOM).

Я застрял в функции removeEvent в строке 18. Какой правильный второй аргумент для функции removeEventListener в этом случае?

Вместо добавления и удаления прослушивателя событий он просто добавляет прослушиватели событий, что можно наблюдать в консоли, где записывается результат строки 8.

Решение должно быть простым ванильным javascript, совместимым с ES5 и предназначенным для запуска в браузере (IE9 +).

+0

удалить слушатель события с ** точными ** теми же аргументами, вы добавляете прослушиватель событий –

ответ

2
  1. Вы можете сначала сохранить запись этого переплетены события в вашем объекте, как:
// Add the event handler 
Film.prototype.bindEvent = function() { 
    // This ensure that the binded event can be removed by removeEvent 
    // even if you call bindEvent many times. 
    if (!this._bindedEvent) { 
    this._bindedEvent = this.eventHandler.bind(this); 
    this.link.addEventListener('click', this._bindedEvent); 
    } 
} 

Затем удалите что:

// Remove the event handler 
Film.prototype.removeEvent = function() { 
    if (this._bindedEvent) { 
    this.link.removeEventListener('click', this._bindedEvent); 
    this._bindedEvent = null; 
    } 
} 

2. Другой способ заключается в переопределении eventhandler в конструкторе:

// The test class definition 
var Film = function() { 
    this.link = document.getElementById('film'); 
    // This first find if self has attr eventHandler, and keep lookup to its prototype. 
    // Then createa binded version of eventhandler and set to this's attr. 
    // So when you try to access `this.eventHandler`, it'll be the binded version instead of Prototype's 
    this.eventHandler = this.eventHandler.bind(this); 
} 

Тогда вы можете просто использовать

// Add the event handler 
Film.prototype.bindEvent = function() { 
    this.link.addEventListener('click', this.eventHandler); 
} 

// Remove the event handler 
Film.prototype.removeEvent = function() { 
    this.link.removeEventListener('click', this.eventHandler); 
} 

Чтобы добавить и удалить его.

1

Когда вы используете .bind(this), как вы здесь: this.link.addEventListener('click', this.eventHandler.bind(this));, вы фактически получаете новую функцию. Когда вы пытаетесь удалить его, вы используете оригинальный обработчик, а remove не может найти обработчик привязки.

От MDN:

Привязать() создает новую функцию, которая при вызове, имеет свою это ключевое слово, установленное на основе предоставленного значения с заданной последовательностью аргументов, предшествующих любому условии, когда вызывается новая функция.

Чтобы исправить это использовать привязку при определении обработчика (codepen - обработчик удаляется через 3 секунды):

// The event handler to add and remove 
Film.prototype.eventHandler = function() { 
    console.log('handled'); 
}.bind(Film); 

// Add the event handler 
Film.prototype.bindEvent = function() { 
    this.link.addEventListener('click', this.eventHandler); 
} 

// Remove the event handler 
Film.prototype.removeEvent = function() { 
    this.link.removeEventListener('click', this.eventHandler); 
} 
+0

Теперь 'this' является окном и уже не является текущим экземпляром' Film', который необходим в обработчике событий. – phippu

+0

Спасибо @phippu - исправлено. –

+0

Хотя мне нравится простота кода, это не сработало для меня, потому что внутри eventHandler 'this' является ссылкой на функцию-конструктор, а не на объект-индуцированный объект. – phippu

Смежные вопросы