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

如何实现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")到阈值距离后,抽屉会自动关闭。

方案二:手动监听触摸/鼠标事件实现自定义滑动

如果原生方案不符合需求,可手动实现滑动逻辑:

  1. 在组件类中定义滑动状态变量:
private startX: number = 0;
private isDragging: boolean = false;
  1. 给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()"
>
  1. 实现滑动处理逻辑:
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;
}
  1. 可选:添加滑动视觉反馈,给抽屉加过渡动画:
.sidebar {
  transition: transform 0.3s ease;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:52:19