Недавно, работая над своим личным сайтом, я столкнулся с интересной проблемой. Я хотел иметь адаптивный веб-сайт, на котором при изменении размера до определенной ширины панель навигации менялась на меню в стиле аккордеона, как показано ниже.
Я создавал свой проект с помощью 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, которую мы установили ранее, однако она вызывается всякий раз, когда пользователь щелкает в любом месте документа. Это работает в мою пользу, так как я хочу, чтобы меню закрывалось во всех случаях, даже при нажатии на страницы в самом меню.
Конечный результат можно найти ниже, поэкспериментируйте с изменением размера экрана и меню!