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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 05:57:05