Показать сообщение отдельно
  #1 (permalink)  
Старый 31.07.2019, 10:49
Новичок на форуме
Отправить личное сообщение для Muvka Посмотреть профиль Найти все сообщения от Muvka
 
Регистрация: 31.07.2019
Сообщений: 1

Нужна критика на скрипт выпадающего меню
Написал скрипт для создания выпадающего меню, с использованием БЭМ нотации. И с использованием css анимации. При этом внешний вид каждого меню можно сделать индивидуальным. Но я понимаю, что вот так вот сразу все сделать хорошо не получится. Поэтому пожалуйста, укажите узкие места.
class DropdownMenu {
    constructor(menu) {
      this._menu = menu; // Само меню
      this._button = this._menu.querySelector('.js-dropdown__toggler'); // Кнопка открытия меню
      this._baseClass = this._menu.dataset.baseClass; // Основной класс блока. Для создания правильного класса с --open
      this._isOpen = false; // Открыто меню или нет

      this._button.addEventListener('click', this._toggle.bind(this));

      // Удаление класса закрывающей анимации
      this._menu.addEventListener('animationend', () => {
        this._menu.classList.remove('js-dropdown--close', `${this._baseClass}--close`);
      });
    }

    _toggle(event) {
      if(event) {
        event.preventDefault();
        event.stopPropagation();
      }

      if(this._isOpen) {
        this.close();
      } else {
        // Если есть открытое меню, закрываем его
        if(DropdownMenu.openedMenu) {
          DropdownMenu.openedMenu.close();
        }

        this.open();
      }
    }

    open() {
      this._menu.classList.add('js-dropdown--open');
      
      if(this._baseClass) {
        this._menu.classList.add(`${this._baseClass}--open`);
      }

      this._isOpen = true;
      // Сохраняем открытое меню
      DropdownMenu.openedMenu = this;
    }

    close() {
      this._menu.classList.add('js-dropdown--close');
      this._menu.classList.remove('js-dropdown--open');

      if(this._baseClass) {
        this._menu.classList.add(`${this._baseClass}--close`);
        this._menu.classList.remove(`${this._baseClass}--open`);
      }

      this._isOpen = false;
      DropdownMenu.openedMenu = null;
    }

    static init(menu) {
      if(!DropdownMenu._initialized) {
        DropdownMenu._initialized = true;

        // Закрытие меню при клике вне меню
        document.addEventListener('click', ({target}) => {
          if(DropdownMenu.openedMenu && !target.closest('.js-dropdown__inner')) {
            DropdownMenu.openedMenu.close();
          }
        });
      }

      return new DropdownMenu(menu);
    }
  }

  const dropdownMenus = document.querySelectorAll('.js-dropdown');

  if(dropdownMenus) {
    [...dropdownMenus].forEach((menu) => {
      DropdownMenu.init(menu);
    });
  }

Последний раз редактировалось Muvka, 31.07.2019 в 10:51.
Ответить с цитированием