关于设置初始值导致canvas位置锁定问题的跟进咨询
问题:设置canvas初始top/left后无法拖动的原因分析
设置canvas的style.top或style.left初始值后,点击canvas无法拖动对应方向;但不设置初始值时,拖动功能正常。比如示例代码中,取消注释canv.style.top = "50px"后,canvas就无法垂直移动;设置了canv.style.left = "50px",则无法水平移动,注释掉top初始值后又能正常垂直移动,请问原因是什么?
示例代码
<!DOCTYPE html> <html> <body> <script> var n=0, canv, ct var body = document.getElementsByTagName("body")[0]; var i,offx=0,offy=0, n=0 canv = document.createElement('canvas'); canv.id = "C"; canv.style.width = "100px"; canv.style.height = "100px"; //canv.style.top = "50px"; commenting out line will let it move canv.style.left = "50px"; canv.style.zIndex = 0; canv.style.position = "absolute"; canv.style.border = "2px solid"; body.appendChild(canv); ct = canv.getContext("2d"); canv.addEventListener('mousedown', function (e) { if (this.style.border == "2px solid"){ this.style.border = "5px solid" offy=e.y-this.style.top offx=e.x-this.style.left } else{this.style.border = "2px solid"} }); canv.addEventListener('mousemove', function (e) { if (this.style.border != "2px solid"){ this.style.top=e.y-offy+"px" this.style.left=e.x-offx+"px" } }); </script> </body> </html>
原因分析
核心问题出在**this.style.top和this.style.left返回的是带px后缀的字符串**,而e.y是数值类型,直接做减法会导致计算错误:
- 当没有设置初始top/left时,
this.style.top是空字符串,e.y - ""会被JS自动转换为数值计算(空字符串视为0),所以offy是正确的数值,后续拖动时计算正常; - 当设置了初始值(比如
"50px"),e.y - "50px"会得到NaN(非数值),后续e.y - offy也会是NaN,把NaNpx赋值给style.top后,浏览器无法识别这个无效值,元素自然不会移动。
修复方案
需要把style.top/left的字符串值转成纯数值再计算,推荐用getBoundingClientRect()获取元素的准确位置(不受inline style限制,还能获取元素的真实布局位置),修复后的关键代码如下:
canv.addEventListener('mousedown', function (e) { if (this.style.border === "2px solid"){ this.style.border = "5px solid" // 获取元素的真实位置信息 const rect = this.getBoundingClientRect(); // 计算鼠标相对于元素左上角的偏移量 offy = e.clientY - rect.top; offx = e.clientX - rect.left; } else { this.style.border = "2px solid" } });
另外建议把e.y改成e.clientY,这是标准的鼠标Y轴坐标属性,兼容性更好。
内容的提问来源于stack exchange,提问作者EV123
相关产品推荐
相关产品推荐

