移动端Sidebar Menu无法自动折叠:需点击外部或路由变化时关闭
It looks like your current implementation relies on mouse events (mouseenter/mouseleave) which don’t translate well to mobile touch interactions, and you’re missing handlers for click-outside and route-change events. Here’s how to fix both issues:
1. Add Click-Outside Handler for Mobile
Update your app-menu.js to detect clicks outside the menu and toggle button, then collapse the menu on mobile:
// Helper to detect mobile viewports (adjust breakpoint to match your design) function isMobile() { return window.innerWidth < 768; } // Expose collapse function globally for Angular access window.modernMenuCollapse = function(){ if($body.hasClass('menu-collapsed') && $body.data('menu') == 'vertical-menu-modern'){ setTimeout(function(){ $('.main-menu, .navbar-header').removeClass('expanded'); if($body.hasClass('menu-collapsed')){ var $listItem = $('.main-menu li.open'), $subList = $listItem.children('ul'); $listItem.addClass('menu-collapsed-open'); $subList.show().slideUp(200, function() { $(this).css('display', ''); }); $listItem.removeClass('open'); // $.app.menu.changeLogo(); } },1); } }; // Original expand function (disabled on mobile) function modernMenuExpand(){ if (!isMobile()) { if( $body.data('menu') == 'vertical-menu-modern'){ $('.main-menu, .navbar-header').addClass('expanded'); if($body.hasClass('menu-collapsed')){ var $listItem = $('.main-menu li.menu-collapsed-open'), $subList = $listItem.children('ul'); $subList.hide().slideDown(200, function() { $(this).css('display', ''); }); $listItem.addClass('open').removeClass('menu-collapsed-open'); // $.app.menu.changeLogo('expand'); } } } } // Original collapse function (disabled on mobile) function modernMenuCollapse(){ if (!isMobile()) { if($body.hasClass('menu-collapsed') && $body.data('menu') == 'vertical-menu-modern'){ setTimeout(function(){ if($('.main-menu:hover').length === 0 && $('.navbar-header:hover').length === 0){ $('.main-menu, .navbar-header').removeClass('expanded'); if($body.hasClass('menu-collapsed')){ var $listItem = $('.main-menu li.open'), $subList = $listItem.children('ul'); $listItem.addClass('menu-collapsed-open'); $subList.show().slideUp(200, function() { $(this).css('display', ''); }); $listItem.removeClass('open'); // $.app.menu.changeLogo(); } } },1); } } } // Click-outside handler for mobile $(document).on('click', function(e) { if (isMobile() && $body.data('menu') == 'vertical-menu-modern') { const isClickInsideMenu = $('.main-menu').is(e.target) || $('.main-menu').has(e.target).length > 0; const isClickInsideToggle = $('.navbar-toggle').is(e.target) || $('.navbar-toggle').has(e.target).length > 0; if (!isClickInsideMenu && !isClickInsideToggle) { window.modernMenuCollapse(); } } }); // Attach original mouse events $('.navbar-header, .main-menu').on('mouseenter', modernMenuExpand).on('mouseleave', modernMenuCollapse);
2. Handle Route Changes to Collapse Menu
Update your sidebar.component.ts to listen for route navigation events and collapse the menu when routes change on mobile:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; import { filter, takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; declare var $: any; declare var modernMenuCollapse: any; // Declare global function @Component({ selector: 'app-sidebar', templateUrl: './sidebar.component.html', }) export class SidebarComponent implements OnInit, OnDestroy { private destroy$ = new Subject<void>(); constructor(private router: Router) { } ngOnInit() { $.getScript('./assets/app/js/core/app-menu.js'); $.getScript('./assets/app/js/core/app.js'); // Listen for successful route navigation this.router.events.pipe( filter(event => event instanceof NavigationEnd), takeUntil(this.destroy$) ).subscribe(() => { // Collapse menu on mobile after route change if (window.innerWidth < 768) { if ($('.main-menu').hasClass('expanded')) { modernMenuCollapse(); } } }); } ngOnDestroy() { // Clean up subscription to avoid memory leaks this.destroy$.next(); this.destroy$.complete(); } }
Key Notes:
- Mobile Breakpoint: Adjust the
768pxvalue inisMobile()to match your app’s responsive design. - Global Function: Exposing
modernMenuCollapseto the window object lets Angular call it directly without extra work. - Memory Management: The
OnDestroyhook cleans up the route subscription to prevent memory leaks in Angular. - Hover Disabling: Mouse hover logic is turned off on mobile since touch devices don’t support hover states.
These changes will ensure your sidebar collapses automatically when clicking outside the menu or navigating to a new route on mobile, while preserving the existing desktop/tablet behavior.
内容的提问来源于stack exchange,提问作者yer

