如何在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
相关产品推荐
相关产品推荐

