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

如何在Angular中用CSS/TypeScript实现左侧拖拽调整尺寸的弹性div

原生CSS的resize:horizontal仅支持从元素右下角/右侧触发尺寸调整,没有内置左侧拖拽的配置。要实现左侧拖拽调整宽度的效果,只需要新增一个左侧拖拽触发区,配合简单的鼠标事件逻辑即可,不需要引入第三方依赖,原有样式表现可以完全保留。

实现代码

1. 样式调整

首先给容器加相对定位,新增左侧拖拽手柄样式,修正盒模型避免尺寸计算偏差:

.resizable_div {
  position: relative;
  border: 1px solid red;
  white-space: nowrap; 
  width: 100px;
  height: 50px;
  line-height: 50px; 
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 5px;
  min-width: 50px;
  max-width: 150px;
  /* 不需要保留原生右侧拖拽能力就删掉下面这行 */
  resize: horizontal;
  cursor: default;
  box-sizing: border-box;
}

/* 左侧拖拽触发手柄 */
.resize-handle-left {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 6px;
  cursor: col-resize;
  background: transparent;
  /* 手柄一半在元素外、一半压在元素边缘,降低对准难度 */
  transform: translateX(-3px);
}

2. 组件模板

在可调整尺寸的div内嵌入左侧拖拽手柄,绑定动态宽度、偏移样式和拖拽启动事件:

<div 
  class="resizable_div"
  [style.width.px]="boxWidth"
  [style.margin-left.px]="boxOffset"
>
  This is an example
  <div 
    class="resize-handle-left"
    (mousedown)="startLeftResize($event)"
  ></div>
</div>

3. 组件TS逻辑

监听鼠标事件计算拖拽偏移,同步更新元素宽度和左外边距,保证拖拽过程中元素右边缘位置固定,符合向左拉变宽、向右拉收窄的交互预期,同时保留原有的宽度限制:

import { Component, HostListener } from '@angular/core';

@Component({
  selector: 'app-resizable-div',
  templateUrl: './resizable-div.component.html',
  styleUrls: ['./resizable-div.component.css']
})
export class ResizableDivComponent {
  // 和原代码初始配置保持一致
  boxWidth = 100;
  readonly minWidth = 50;
  readonly maxWidth = 150;
  boxOffset = 0;

  private isResizing = false;
  private initMouseX = 0;
  private initWidth = 0;
  private initOffset = 0;

  startLeftResize(e: MouseEvent) {
    e.preventDefault();
    this.isResizing = true;
    this.initMouseX = e.clientX;
    this.initWidth = this.boxWidth;
    this.initOffset = this.boxOffset;
  }

  @HostListener('window:mousemove', ['$event'])
  onDrag(e: MouseEvent) {
    if (!this.isResizing) return;

    const moveDelta = e.clientX - this.initMouseX;
    // 向右拖拽moveDelta为正,宽度收窄;向左拖拽为负,宽度增加
    let targetWidth = this.initWidth - moveDelta;
    // 限制宽度在设定的最小/最大值范围内
    targetWidth = Math.max(this.minWidth, Math.min(targetWidth, this.maxWidth));

    // 宽度变化量同步反向调整左偏移,保证元素右边缘位置不跳动
    const widthChange = targetWidth - this.initWidth;
    this.boxOffset = this.initOffset - widthChange;
    this.boxWidth = targetWidth;
  }

  @HostListener('window:mouseup')
  endResize() {
    this.isResizing = false;
  }
}
关键注意点
  • 鼠标移动、松开事件绑定在window上,就算拖拽过程中鼠标移出元素范围,也不会出现拖拽中断的问题
  • 拖拽手柄做了内外各3px的触发范围,不需要精准对准1px的边框就能触发拖拽,交互更顺滑
  • 如果你的可调整div是绝对定位元素,把模板里的[style.margin-left.px]换成[style.left.px]即可,逻辑完全一致
  • 保留了原代码的resize:horizontal配置,默认同时支持左右两侧拖拽调整,不需要的话直接删掉这行css即可

内容的提问来源于stack exchange,提问作者Cem Özbey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:51:27