Angular如何实现类似Trello的鼠标拖拽水平滚动功能
Angular 鼠标拖拽触发水平滚动实现方案
Angular 没有内置专门的拖拽滚动API,你可以通过原生事件结合 Angular 的模板事件绑定实现完全自定义的交互效果,无需依赖第三方库,实现逻辑如下:
1. 模板绑定事件
给需要滚动的容器绑定对应鼠标事件,同时用模板变量标记容器方便组件内获取DOM实例:
<div class="scroll-container" (mousedown)="onMouseDown($event)" (mousemove)="onMouseMove($event)" (mouseup)="onMouseUp()" (mouseleave)="onMouseUp()" #scrollContainer > <!-- 横向排列的业务内容 --> <div class="scroll-item" *ngFor="let item of contentList">{{item}}</div> </div>
2. 组件逻辑实现
import { Component, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-horizontal-drag-scroll', templateUrl: './horizontal-drag-scroll.component.html', styleUrls: ['./horizontal-drag-scroll.component.css'] }) export class HorizontalDragScrollComponent { // 获取滚动容器DOM实例 @ViewChild('scrollContainer') scrollContainer!: ElementRef<HTMLDivElement>; // 状态变量 private isDragging = false; private startX = 0; private initScrollLeft = 0; // 鼠标按下触发 onMouseDown(e: MouseEvent): void { this.isDragging = true; // 记录初始坐标和容器初始滚动距离 this.startX = e.pageX - this.scrollContainer.nativeElement.offsetLeft; this.initScrollLeft = this.scrollContainer.nativeElement.scrollLeft; // 修改交互样式,禁止选中文本避免干扰 this.scrollContainer.nativeElement.style.cursor = 'grabbing'; this.scrollContainer.nativeElement.style.userSelect = 'none'; } // 鼠标移动触发 onMouseMove(e: MouseEvent): void { if (!this.isDragging) return; e.preventDefault(); // 计算鼠标偏移量,对应更新容器滚动位置 const currentX = e.pageX - this.scrollContainer.nativeElement.offsetLeft; const offsetX = (currentX - this.startX) * 1.5; // 1.5为滚动灵敏度,可自行调整 this.scrollContainer.nativeElement.scrollLeft = this.initScrollLeft - offsetX; } // 鼠标抬起/离开容器触发 onMouseUp(): void { this.isDragging = false; // 恢复默认样式 this.scrollContainer.nativeElement.style.cursor = 'grab'; this.scrollContainer.nativeElement.style.removeProperty('user-select'); } // 测试用的内容列表 contentList = Array.from({length: 30}, (_, i) => `内容项 ${i + 1}`); }
3. 容器样式配置
.scroll-container { display: flex; overflow-x: auto; overflow-y: hidden; width: 100%; height: 120px; gap: 16px; padding: 16px; cursor: grab; /* 可选:隐藏默认滚动条 */ &::-webkit-scrollbar { display: none; } -ms-overflow-style: none; scrollbar-width: none; } .scroll-item { flex-shrink: 0; width: 180px; height: 100%; background: #f5f5f5; border-radius: 8px; display: flex; align-items: center; justify-content: center; }
自定义优化方向
- 如需兼容移动端触摸操作,对应添加
touchstart、touchmove、touchend事件即可,逻辑和鼠标事件完全一致,坐标取e.touches[0].pageX即可 - 如需添加惯性滚动效果,可在
onMouseUp事件中计算鼠标移动的瞬时速度,给滚动容器添加缓动动画即可 - 可以根据业务需求调整滚动灵敏度、拖拽过程的动画效果等参数
内容的提问来源于stack exchange,提问作者MoeinDeveloper
相关产品推荐
相关产品推荐

