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
相关产品推荐
相关产品推荐

