如何实现Angular中mat-drawer的滑动关闭功能?
实现Angular Mat-Drawer的滑动关闭功能
我在Angular应用中使用了mat-drawer,目前已实现通过点击按钮打开和关闭抽屉的功能。但我还希望支持用户通过滑动抽屉使其远离容器的方式来关闭它。当前代码如下:
<div class="widget-map-container"> <mat-card class="mat-elevation-z2 card p-0"> <mat-drawer-container [hasBackdrop]="false" class="mat-drawer-container"> <mat-drawer mode="over" [opened]="sidebar.open" position="end" class="sidebar"> <app-list-markers-areas [areas]="geometricLayers.areas" [markers]="geometricLayers.markers" (closeEvent)="sidebar.open = !sidebar.open" (itemSelectEvent)="mapService.centerOnGeometryLayer($event, map)" class="sidebar-list" ></app-list-markers-areas> </mat-drawer> <mat-drawer-content> <div class="map-container" (resized)="resizeEvent$.next()" [id]="mapHtmlElementId" (click)="closeSidebar()"></div> </mat-drawer-content> </mat-drawer-container>
实现滑动关闭的两种方案
方案一:利用MatDrawer原生拖拽交互(推荐)
Angular Material的mat-drawer自带拖拽关闭能力,只需调整几个配置:
- 确保
mat-drawer-container的hasBackdrop设为true(若不需要背景遮罩,可通过CSS隐藏但保留功能) - 抽屉处于
over或push模式时,拖拽边缘即可触发关闭逻辑
修改模板代码:
<mat-drawer-container hasBackdrop="true" class="mat-drawer-container"> <mat-drawer mode="over" [opened]="sidebar.open" position="end" class="sidebar"> <!-- 抽屉内容保持不变 --> </mat-drawer> </mat-drawer-container>
若不需要背景遮罩,添加CSS隐藏:
.mat-drawer-container .mat-drawer-backdrop { background-color: transparent; pointer-events: none; /* 避免遮罩拦截地图点击事件 */ }
此时用户向右拖拽抽屉(因position="end")到阈值距离后,抽屉会自动关闭。
方案二:手动监听触摸/鼠标事件实现自定义滑动
如果原生方案不符合需求,可手动实现滑动逻辑:
- 在组件类中定义滑动状态变量:
private startX: number = 0; private isDragging: boolean = false;
- 给
mat-drawer绑定事件监听:
<mat-drawer mode="over" [opened]="sidebar.open" position="end" class="sidebar" (mousedown)="onDragStart($event)" (touchstart)="onDragStart($event)" (mousemove)="onDragMove($event)" (touchmove)="onDragMove($event)" (mouseup)="onDragEnd()" (touchend)="onDragEnd()" (mouseleave)="onDragEnd()" >
- 实现滑动处理逻辑:
onDragStart(event: MouseEvent | TouchEvent): void { this.isDragging = true; this.startX = event instanceof MouseEvent ? event.clientX : event.touches[0].clientX; } onDragMove(event: MouseEvent | TouchEvent): void { if (!this.isDragging) return; const currentX = event instanceof MouseEvent ? event.clientX : event.touches[0].clientX; const deltaX = currentX - this.startX; // 向右滑动超过50px时关闭抽屉,可根据需求调整阈值 if (deltaX > 50) { this.sidebar.open = false; this.isDragging = false; } } onDragEnd(): void { this.isDragging = false; }
- 可选:添加滑动视觉反馈,给抽屉加过渡动画:
.sidebar { transition: transform 0.3s ease; }
内容的提问来源于stack exchange,提问作者ojoaovitoraraujo
相关产品推荐
相关产品推荐

