lavezzi1
@lavezzi1

Как лучше написать функцию для add/remove event listeners?

Привет. Есть класс, в конструкторе которого вызываю этот метод для подписки на события:
addEvenetsListeners() {
    this.options.triggers.forEach((event) => {
      switch (event) {
        case 'click': {
          this.el.addEventListener('click', this.toggle.bind(this), false);
          document.addEventListener('click', this.clickOutsideHandler, false);
          break;
        }
        case 'hover': {
          this.el.addEventListener('mouseenter', this.show.bind(this), false);
          this.el.addEventListener('mouseleave', this.hide.bind(this), true);
          break;
        }
        case 'focus': {
          this.el.addEventListener('focus', this.show.bind(this), false);
          this.el.addEventListener('blur', this.hide.bind(this), true);
          break;
        }
        default:
          throw new Error(`This ${event} is not defined.`);
      }
    });
  }


События передаются в массиве типа ['hover', 'click'].

Вопрос в том, как правильней всего организовать эту функцию так, чтобы в методе destroy() ее вызывать для удаления слушателей?
  • Вопрос задан
  • 324 просмотра
Пригласить эксперта
Ответы на вопрос 1
teknik2008
@teknik2008
Расскажите про GOLANG. Мне интересно
Мое виденье, хотя можно реализовать через события, а не через элементы. Но вообщем кешировать обработчики, в общем хранилище.
Тык
class Elems {
    constructor() {
        this.listeners = new Map();// коллекция элементов и обрабочиков
        this.options = { triggers: ['click'] }
        this.el=document.documentElement;
    }

    toggle(){}

    show(){}

    hide(){}

    clickOutsideHandler(){}

    addEvenetsListeners() {
        /**
        * Функция обновления коллекции обработчиков на элементе
         * 
         * @author teknik2008
         * @param {HTMLElements} el - элемент для которого устанавливаетсся обработчик 
         * @param {string} event - событие которое на которое устанавливаетсся обработчик 
         * @param {function} handler - обработчик события
         * @returns {void}
         */
        let listeners = this.listeners;
        function addListenersCollections(el, event, handler) {
            if (!listeners.has(el)) {
                let model = {};
                model[event] = [];
                model[event].push(handler);
                listeners.set(el, model);
                return;
            }
            let model = listeners.get(el);
            model[event] = event in model ? model[event] : [];
            model[event].push(handler);
            listeners.set(el, model);
        }
        this.options.triggers.forEach((event) => {
            switch (event) {
                case 'click': {
                    let elHandler = this.toggle.bind(this);
                    this.el.addEventListener('click', elHandler, false);
                    addListenersCollections(this.el, 'click', elHandler);

                    let documentHandler = this.clickOutsideHandler;
                    document.addEventListener('click', documentHandler, false);
                    addListenersCollections(document, 'click', documentHandler);
                    break;
                }
                case 'hover': {
                    this.el.addEventListener('mouseenter', this.show.bind(this), false);
                    this.el.addEventListener('mouseleave', this.hide.bind(this), true);
                    break;
                }
                case 'focus': {
                    this.el.addEventListener('focus', this.show.bind(this), false);
                    this.el.addEventListener('blur', this.hide.bind(this), true);
                    break;
                }
                default:
                    throw new Error(`This ${event} is not defined.`);
            }
        });
    }

    removeEventListener() {
        let listeners = this.listeners;
        let elems = [this.el, document];
        this.options.triggers.forEach((event) => {// тут я понял что можно было коллекцию сделать через события, но я думаю мысель понятна
            elems.forEach(el => {
                if (!listeners.has(el)) {
                    return;
                }
                let model = listeners.get(el);
                if(!(event in model)){
                    return;
                }
                let handlers=model[event];
                handlers.forEach(handler=>{
                    console.log(el,event,handler)
                    el.removeEventListener(event,handler);
                })
            })
        })
    }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
18 апр. 2024, в 21:56
2000 руб./за проект
18 апр. 2024, в 21:00
150 руб./за проект