You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移动端Sidebar Menu无法自动折叠:需点击外部或路由变化时关闭

Fix for Mobile Sidebar Menu Auto-Collapse Issues

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 768px value in isMobile() to match your app’s responsive design.
  • Global Function: Exposing modernMenuCollapse to the window object lets Angular call it directly without extra work.
  • Memory Management: The OnDestroy hook 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:57:40