纯JS实现盒子宽度调整:左侧拉伸位置跳动问题求助
解决拖拽盒子左侧调整宽度时的位置跳动问题
问题根源
你在左侧调整宽度时,错误地使用盒子的初始宽度divWidth计算left属性值,完全偏离了盒子位置的实际变化逻辑,导致位置跳动。正确逻辑应该基于盒子的初始左侧位置和鼠标移动量,同步更新宽度与位置。
修正方案
- 在左侧手柄的
mousedown事件中,额外记录盒子的初始左侧位置:
wlSize.addEventListener('mousedown', function(e){ wlSizeDown = true; wlSizeOffset = { x: e.clientX, y: e.clientY } divWidth = parseInt(div.style.width, 10); // 新增:记录盒子初始left值 divLeft = parseInt(div.style.left, 10); });
- 修改
mousemove事件中左侧调整的逻辑,基于鼠标移动量同步更新宽度和位置:
if(wlSizeDown){ // 计算鼠标水平移动量 const deltaX = mousePosition.x - wlSizeOffset.x; // 宽度 = 初始宽度 - 移动量(左移时移动量为负,宽度增加;右移时移动量为正,宽度减少) div.style.width = (divWidth - deltaX) + 'px'; // 左侧位置 = 初始left + 移动量(左移时位置左移,右移时位置右移) div.style.left = (divLeft + deltaX) + 'px'; }
完整修正代码
var mousePosition; var offset; var wrSizeOffset, wlSizeOffset, hbSizeOffset; var div; var isDown = false; var wlSizeDown, wrSizeDown, htSizeDown, hbSizeDown = false; var divWidth, divHeight, divLeft; // 新增divLeft变量 div = document.createElement('div'); div.style.position = 'relative'; div.style.left = '100px'; div.style.top = '100px'; div.style.width = '100px'; div.style.height = '100px'; div.style.backgroundColor = 'red'; div.style.border = '1px solid black'; wrSize = document.createElement('div'); wrSize.style.position = 'absolute'; wrSize.style.right = '-10px'; wrSize.style.top = '40px'; wrSize.style.width = '20px'; wrSize.style.height = '20px'; wrSize.style.backgroundColor = 'black'; wrSize.style.border = '1px solid black'; wlSize = document.createElement('div'); wlSize.style.position = 'absolute'; wlSize.style.left = '-10px'; wlSize.style.top = '40px'; wlSize.style.width = '20px'; wlSize.style.height = '20px'; wlSize.style.backgroundColor = 'black'; wlSize.style.border = '1px solid black'; htSize = document.createElement('div'); htSize.style.position = 'absolute'; htSize.style.left = '40px'; htSize.style.top = '-10px'; htSize.style.width = '20px'; htSize.style.height = '20px'; htSize.style.backgroundColor = 'black'; htSize.style.border = '1px solid black'; hbSize = document.createElement('div'); hbSize.style.position = 'absolute'; hbSize.style.left = '40px'; hbSize.style.bottom = '-10px'; hbSize.style.width = '20px'; hbSize.style.height = '20px'; hbSize.style.backgroundColor = 'black'; hbSize.style.border = '1px solid black'; document.body.appendChild(div); div.appendChild(wrSize); div.appendChild(wlSize); div.appendChild(htSize); div.appendChild(hbSize); div.addEventListener('mousedown', function(e){ isDown = true; offset = { x: div.offsetLeft - e.clientX, y: div.offsetTop - e.clientY } }); wrSize.addEventListener('mousedown', function(e){ wrSizeDown = true; wrSizeOffset = { x: e.clientX, y: e.clientY } divWidth = parseInt(div.style.width, 10); }); wlSize.addEventListener('mousedown', function(e){ wlSizeDown = true; wlSizeOffset = { x: e.clientX, y: e.clientY } divWidth = parseInt(div.style.width, 10); divLeft = parseInt(div.style.left, 10); // 记录初始left }); hbSize.addEventListener('mousedown', function(e){ hbSizeDown = true; hbSizeOffset = { x: e.clientX, y: e.clientY } divHeight = parseInt(div.style.height, 10); }); document.addEventListener('mouseup', function(e){ isDown = false; wrSizeDown = false; wlSizeDown = false; hbSizeDown = false; }); document.addEventListener('mousemove', function(e){ mousePosition = { x: e.clientX, y: e.clientY } if(isDown && (!wrSizeDown && !wlSizeDown && !hbSizeDown)){ div.style.left = (mousePosition.x + offset.x) + 'px'; div.style.top = (mousePosition.y + offset.y) + 'px'; } if(wrSizeDown){ div.style.width = divWidth + mousePosition.x - wrSizeOffset.x + 'px'; } if(hbSizeDown){ div.style.height = divHeight + mousePosition.y - hbSizeOffset.y + 'px'; } if(wlSizeDown){ const deltaX = mousePosition.x - wlSizeOffset.x; div.style.width = (divWidth - deltaX) + 'px'; div.style.left = (divLeft + deltaX) + 'px'; } });
body { margin: 0px; } * { box-sizing: border-box; } #box{ position: absolute; display: block; top: 50px; left: 50px; width: 200px; height: 200px; background-color: #d80000; border: 1px solid #000; }
补充说明
若要实现顶部调整高度的功能,逻辑与左侧调整一致:
- 在顶部手柄的
mousedown事件中记录初始top值和初始高度 - 在
mousemove中计算垂直移动量deltaY,更新高度divHeight - deltaY和top值divTop + deltaY
内容的提问来源于stack exchange,提问作者FarrisFahad
相关产品推荐
相关产品推荐

