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

Я создавал свой проект с помощью EmberJS, мощного внешнего MVC-фреймворка, который было довольно интересно использовать. Было легко освоиться и приступить к разработке этого нового проекта. У Ember есть много преимуществ, но самым важным аспектом, который я бы назвал, является скорость. Быстрая загрузка страниц = довольные посетители сайта, и ember, безусловно, выполняет эту задачу.

Теперь о моей проблеме: после того, как мое меню аккордеона скользнуло вниз, мне нужно было, чтобы оно снова скользило вверх. Было относительно легко начать работать с самой кнопкой, я просто назначил ей действие: toggleSidebarCollapse() и написал этот код в своем контроллере application.js.

/app/controllers/application.js
export default Ember.Controller.extend({
  sideSidebarCollapse: false,
  actions: {
    toggleSidebarCollapse() {
      var x = $("#custom-collapse")
      if ( !this.get('sideSidebarCollapse') ){
        x.slideDown();
        this.toggleProperty('sideSidebarCollapse');
        Ember.run.next(this,function(){
          var _this = this;
          $(document).one('click',function() {
            _this.toggleProperty('sideSidebarCollapse');
            x.slideUp();
          });
        });
      }
    }
  }
});

Этот код устанавливает переменную: sideSidebarCollapse и устанавливает для нее значение false, заявляя, что боковая панель по умолчанию должна быть свернута. Затем всякий раз, когда вызывается действие toggleSidebarCollapse, мы проверяем, свернуто ли оно, и если да, то вызываем метод slideDown() в меню аккордеона. Это создает приятный визуальный эффект появления меню.

Однако нам все еще нужно обработать закрытие меню. В моем случае я хотел, чтобы он закрывался всякий раз, когда пользователь щелкал где-нибудь, чего не было в меню. Для этого я запускаю вызов Ember.run.next. Это запускает отдельный цикл, который будет выполняться после того, как управление будет возвращено системе (~ 1 мс). Это гарантирует, что внутренний код не будет обрабатываться в том же контексте, что и действие. Если бы я не вызывал функцию Ember.run.next, мое событие «щелчок» все еще регистрировалось бы, когда я нажимал кнопку, вызывая выполнение внутреннего кода, а мой аккордеон открывался и закрывался сразу после этого.

Что касается следующего раздела кода, я вызываю $(document).one, что означает, что событие «щелчок» произойдет только один раз. Сам обработчик событий просто вызывает slideUp() и переключает переменную sideSidebarCollapse, которую мы установили ранее, однако она вызывается всякий раз, когда пользователь щелкает в любом месте документа. Это работает в мою пользу, так как я хочу, чтобы меню закрывалось во всех случаях, даже при нажатии на страницы в самом меню.

Конечный результат можно найти ниже, поэкспериментируйте с изменением размера экрана и меню!



Говард Дин Уоттс | Разработчик программного обеспечения
www.hdwatts.com