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

Angular 16.0.2侧边栏无法推动内容区域,window.innerWidth不生效

问题描述

我使用Angular 16.0.2开发项目,期望点击侧边栏的启动按钮时,侧边栏向右展开并推动左侧内容区域自适应调整,但该功能未生效——侧边栏仅覆盖在内容上方,并未推动内容区域。我已在ngOnInit钩子中通过window.innerWidth获取屏幕宽度,但问题仍存在。

相关代码

Sidenav.component.html

<div class="sidenav" [ngClass]="collapsed ? 'sidenav-collapsed' : ''">
  <div class="logo-container">
    <button class="logo" (click)="toggleCollapse()">T</button>
    <div class="logo-text" @fadeInOut *ngIf="collapsed">ThesisWApp</div>
    <button class="btn-close" @rotate *ngIf="collapsed" (click)="closeSidenav()">
      <i class="fal fa-times close-icon"></i>
    </button>
  </div>
  <ul class="sidenav-nav">
    <li class="sidenav-nav-item" *ngFor="let data of navData">
      <a class="sidenav-nav-link" [routerLink]="[data.routeLink]"
        routerLinkActive="active"
        [routerLinkActiveOptions]="{exact: true}"
      >
        <i class="sidenav-link-icon" [class]="data.icon"></i>
        <span class="sidenav-link-text" @fadeInOut *ngIf="collapsed">
          {{data.label}}
        </span>
      </a>
    </li>
  </ul>
</div>

Sidenav.component.ts

import { Component, Output, EventEmitter, HostListener, OnInit } from '@angular/core';
import { navbarData } from './nav-data';
import { animate, keyframes, style, transition, trigger } from '@angular/animations';

interface SideNavToggle{
  screenWidth: number;
  collapsed: boolean
}

@Component({
  selector: 'app-sidenav',
  templateUrl: './sidenav.component.html',
  styleUrls: ['./sidenav.component.scss'],
  animations: [
    trigger('fadeInOut',[
      transition(':enter',[
        style({opacity:0}),
        animate('350ms',
        style({opacity:1})
        )
      ]),
      transition(':leave',[
        style({opacity:1}),
        animate('350ms',
        style({opacity:0})
        )
      ])
    ]),
    trigger('rotate', [
      transition(':enter', [
        animate('1000ms', 
          keyframes([
            style({transform: 'rotate(0deg)', offset: '0'}),
            style({transform: 'rotate(2turn)', offset: '1'})
          ])
        )
      ])
    ])
  ]
})

export class SidenavComponent implements OnInit {

  @Output() onToggleSideNav: EventEmitter<SideNavToggle> = new EventEmitter();
  collapsed = false;
  screenWidth = 0;
  navData = navbarData;

  @HostListener('window:resize', ['$event'])
  onWindowResize(){
    this.screenWidth = window.innerWidth;
    if (this.screenWidth <= 768){
      this.collapsed = false;
      this.onToggleSideNav.emit({collapsed: this.collapsed, screenWidth: this.screenWidth});
    }
  }

  ngOnInit(): void {
    this.screenWidth = window.innerWidth;
  }

  toggleCollapse(): void {
    this.collapsed = !this.collapsed;
    this.onToggleSideNav.emit({collapsed: this.collapsed, screenWidth: this.screenWidth});
  }

  closeSidenav(): void {
    this.collapsed = false;
    this.onToggleSideNav.emit({collapsed: this.collapsed, screenWidth: this.screenWidth});
  }

}

补充说明

我原本认为通过window.innerWidth可以实现该功能,但实际未生效,问题截图如下:
侧边栏覆盖内容区域截图


解决办法

1. 修正侧边栏CSS定位与布局

侧边栏覆盖内容大多是因为使用position: absolute/fixed脱离了文档流,改成相对定位并配合flex布局:

.sidenav {
  width: 60px; // 折叠状态宽度
  transition: width 0.3s ease;
  position: relative; // 替换absolute/fixed
  background-color: #你的侧边栏颜色;
}

.sidenav-collapsed {
  width: 250px; // 展开状态宽度
}

2. 父组件接收侧边栏状态并调整内容区域

你的侧边栏组件已经通过@Output发出折叠状态,但父组件需要接收事件并动态调整内容区域布局:

父组件模板(示例:app.component.html)

<div class="app-container">
  <app-sidenav (onToggleSideNav)="handleSideNavToggle($event)"></app-sidenav>
  <main class="content-area" [style.margin-left]="sidebarMargin">
    <!-- 页面内容 -->
  </main>
</div>

父组件TS(示例:app.component.ts)

import { Component } from '@angular/core';

interface SideNavToggle {
  collapsed: boolean;
  screenWidth: number;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  sidebarMargin = '60px'; // 初始对应折叠状态宽度

  handleSideNavToggle(event: SideNavToggle) {
    // 根据侧边栏状态设置内容区域左边距
    this.sidebarMargin = event.collapsed ? '250px' : '60px';
  }
}

父容器CSS(示例:app.component.scss)

用flex布局让侧边栏和内容区域并排,内容区域自动占满剩余空间:

.app-container {
  display: flex;
  height: 100vh;
}

.content-area {
  flex: 1;
  padding: 1rem;
  transition: margin-left 0.3s ease; // 和侧边栏过渡动画保持一致
}

3. 响应式适配优化

结合window.innerWidth的逻辑,在小屏幕下自动调整内容区域边距:

handleSideNavToggle(event: SideNavToggle) {
  if (event.screenWidth <= 768) {
    this.sidebarMargin = '0px';
  } else {
    this.sidebarMargin = event.collapsed ? '250px' : '60px';
  }
}

内容的提问来源于stack exchange,提问作者ydct

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:50:02