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

Angular中拖动黑色边框实现粉色矩形横向滚动功能故障排查

问题描述

想要实现一个包含文本的粉色矩形,通过拖动黑色边框实现横向滚动(高度不变,宽度可变),但当前代码无法正常工作,代码如下:

HTML代码

<div class="pink-rectangle" [ngStyle]="{ 'width.px': rectangleWidth }">
<div class="scrollable-rectangle">
  <div class="text-content">
   test test 
  </div>
</div>
<div class="black-rectangle" [ngStyle]="{ 'width.px': rectangleWidth - 20 }" (mousedown)="onMouseDown($event)">
</div>
</div>

CSS代码

.pink-rectangle {
  background-color: pink;
  position: relative;
  overflow: hidden;
  height: 200px;
}

.scrollable-rectangle {
  overflow-x: scroll;
  white-space: nowrap;
  height: 100%;
}

.text-content {
  display: inline-block;
  padding: 10px;
  font-weight: bold;
}

.black-rectangle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: transparent;
  border: 2px solid black;
  width: 80%;
  height: 80%;
  z-index: 1;
  pointer-events: none;
}

TS代码

rectangleWidth = 400;
initialX = 0;

onMouseDown(event: MouseEvent) {
  this.initialX = event.clientX;
  document.addEventListener('mousemove', this.onMouseMove);
  document.addEventListener('mouseup', this.onMouseUp);
}

onMouseMove = (event: MouseEvent) => {
  const deltaX = event.clientX - this.initialX;
  this.rectangleWidth += deltaX;
  this.initialX = event.clientX;
}

onMouseUp = () => {
  document.removeEventListener('mousemove', this.onMouseMove);
  document.removeEventListener('mouseup', this.onMouseUp);
}
问题分析与修复方案

核心问题

  1. 黑色边框设置了pointer-events: none,导致鼠标点击事件完全无法触发,拖动功能直接失效。
  2. 拖动逻辑未限制最小宽度,容易出现宽度为负的异常情况。
  3. 黑色边框居中定位,拖动体验不直观,用户难以关联到宽度调整和滚动操作。

修复后完整代码

HTML

<div class="pink-rectangle" [ngStyle]="{ 'width.px': rectangleWidth }">
  <div class="scrollable-rectangle" #scrollable>
    <div class="text-content">
      test test test test test test test test test test test test test test test test test test
    </div>
  </div>
  <div class="black-rectangle" (mousedown)="onMouseDown($event, scrollable)">
  </div>
</div>

CSS

.pink-rectangle {
  background-color: pink;
  position: relative;
  overflow: hidden;
  height: 200px;
  min-width: 100px; /* 限制最小宽度,避免异常 */
}

.scrollable-rectangle {
  overflow-x: scroll;
  white-space: nowrap;
  height: 100%;
}

.text-content {
  display: inline-block;
  padding: 10px;
  font-weight: bold;
}

.black-rectangle {
  position: absolute;
  top: 10%;
  left: 10%;
  right: 10%;
  bottom: 10%;
  background-color: transparent;
  border: 2px solid black;
  z-index: 1;
  cursor: ew-resize; /* 显示横向拖动光标,提示可操作 */
}

TS

rectangleWidth = 400;
initialX = 0;
initialWidth = 0;

onMouseDown(event: MouseEvent, scrollable: HTMLElement) {
  this.initialX = event.clientX;
  this.initialWidth = this.rectangleWidth;
  // 绑定临时函数,确保移除事件时能精准匹配
  const handleMouseMove = (e: MouseEvent) => this.onMouseMove(e, scrollable);
  const handleMouseUp = () => this.onMouseUp(handleMouseMove, handleMouseUp);
  
  document.addEventListener('mousemove', handleMouseMove);
  document.addEventListener('mouseup', handleMouseUp);
}

onMouseMove(event: MouseEvent, scrollable: HTMLElement) {
  const deltaX = event.clientX - this.initialX;
  // 限制最小宽度为100px,避免宽度异常
  this.rectangleWidth = Math.max(100, this.initialWidth + deltaX);
  
  // 同步调整滚动位置,实现拖动边框时的横向滚动效果
  const scrollDelta = deltaX * (scrollable.scrollWidth / this.rectangleWidth);
  scrollable.scrollLeft += scrollDelta;
}

onMouseUp(handleMouseMove: any, handleMouseUp: any) {
  document.removeEventListener('mousemove', handleMouseMove);
  document.removeEventListener('mouseup', handleMouseUp);
}

修复说明

  • 移除pointer-events: none,添加cursor: ew-resize,让黑色边框能响应鼠标事件并提示可拖动。
  • 调整黑色边框定位,使其贴合粉色矩形内部,拖动操作更直观。
  • 增加最小宽度限制,避免宽度变为负数导致布局崩溃。
  • 拖动时同步调整滚动容器的scrollLeft,实现宽度变化与横向滚动联动的效果。
  • 使用临时函数绑定事件,解决事件移除时的上下文匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 07:45:03