如何实现仅拖拽Div端点调整大小?(甘特图场景)
解决方案
要实现仅在Div的左右端点拖拽时调整尺寸,核心是判断鼠标点击位置是否处于元素的边缘区域,只有在指定范围内才触发缩放逻辑。以下是适配甘特图场景的修改后代码:
taskDurationEl.tabIndex = 0; const RESIZE_THRESHOLD = 10; // 定义可拖拽的边缘宽度(单位:px) let isDragging = false; let dragType = null; // 标记拖拽类型:'left' 或 'right' let initialWidth = 0; let initialMouseX = 0; let initialLeft = 0; taskDurationEl.addEventListener('mousedown', function(e) { const rect = this.getBoundingClientRect(); const clickX = e.clientX - rect.left; // 计算点击位置相对于元素左侧的偏移量 // 判断点击位置是否在左边缘或右边缘范围内 if (clickX <= RESIZE_THRESHOLD) { dragType = 'left'; isDragging = true; initialWidth = rect.width; initialMouseX = e.clientX; initialLeft = rect.left; } else if (clickX >= rect.width - RESIZE_THRESHOLD) { dragType = 'right'; isDragging = true; initialWidth = rect.width; initialMouseX = e.clientX; } // 点击中间区域则不触发任何拖拽逻辑 }); document.addEventListener('mousemove', function(e) { if (!isDragging || !dragType) return; const deltaX = e.clientX - initialMouseX; let newWidth = initialWidth; if (dragType === 'left') { // 左端点拖拽:调整宽度+位置,保证任务条右端点不变(适配甘特图逻辑) newWidth = initialWidth - deltaX; newWidth = Math.max(newWidth, 50); // 限制最小宽度,避免元素过窄 taskDurationEl.style.width = `${newWidth}px`; taskDurationEl.style.left = `${initialLeft + deltaX}px`; } else if (dragType === 'right') { // 右端点拖拽:仅调整宽度 newWidth = initialWidth + deltaX; newWidth = Math.max(newWidth, 50); taskDurationEl.style.width = `${newWidth}px`; } }); document.addEventListener('mouseup', function(e) { if (isDragging && dragType) { // 拖拽结束后触发原有回调逻辑 if (dragType === 'left') { taskDurationElDragged = taskDurationEl; onTaskDurationDropSize(e); } else if (dragType === 'right') { taskDurationElDragged = taskDurationEl; onTaskDurationIncreaseSize(e); } } // 重置拖拽状态 isDragging = false; dragType = null; });
关键修改说明:
- 边缘范围判断:通过
getBoundingClientRect()获取元素尺寸与位置,计算鼠标点击点的相对偏移量,仅在左右边缘的RESIZE_THRESHOLD范围内触发拖拽。 - 拖拽状态管理:用
dragType标记当前拖拽的端点类型,非边缘点击直接忽略后续逻辑。 - 甘特图适配:左端点拖拽时同步调整元素
left属性,保证任务条结束位置不变,符合甘特图任务开始时间调整的业务逻辑。 - 全局事件绑定:将
mousemove和mouseup绑定到document,避免鼠标移出元素时丢失拖拽状态。
内容的提问来源于stack exchange,提问作者Asad Hashmi
相关产品推荐
相关产品推荐

