触摸拖拽事件中保持图像居中的实现问题
解决方案:触摸拖拽时让图像中心对齐触摸点
以下是修改后的完整代码,实现触摸图像任意位置时,图像中心自动跳转到触摸点,并在拖拽过程中保持中心跟随触摸点移动:
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width,user-scalable=no"> <meta charset="UTF-8"> <style> html, body { height: 100%; margin: 0; padding: 0; } @media screen and (orientation: landscape) { .chessboard { height: 90%; aspect-ratio : 1 / 1; margin: 0 auto; display: flex; flex-wrap: wrap; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } } @media screen and (orientation: portrait) { .chessboard { width: 90%; aspect-ratio : 1 / 1; margin: 0 auto; display: flex; flex-wrap: wrap; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } } .row{ height: 12.5%; width: 100%; display: flex; } .square { height: 100%; width: 12.5%; position: relative; box-sizing: border-box; } .white { background-color: #f1d8b0; } img{ position: fixed; /* 改为fixed,脱离父容器,基于视口定位 */ width: 90px; /* 使用固定尺寸,确保偏移计算准确 */ height: 90px; cursor: grab; } </style> </head> <body> <script> let d = document.createElement('div'); d.setAttribute('class','chessboard') document.body.appendChild(d); // 提前添加棋盘到body,避免重复添加 for (let i = 0; i <8; i++){ let e = document.createElement('div'); e.setAttribute('class','row'); d.appendChild(e); let f = document.createElement('div'); f.setAttribute('class','square white'); e.appendChild(f); let img = document.createElement('img'); img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Location_dot_blue.svg/1200px-Location_dot_blue.svg.png"; // 初始化图像位置:居中在对应方格内 img.onload = function() { const squareRect = f.getBoundingClientRect(); const centerX = squareRect.left + squareRect.width / 2; const centerY = squareRect.top + squareRect.height / 2; img.style.left = `${centerX - img.offsetWidth/2}px`; img.style.top = `${centerY - img.offsetHeight/2}px`; }; img.addEventListener('touchstart', function(e) { img.style.zIndex = 10; // 提升层级,确保拖拽时在最上层 }); img.addEventListener("touchmove", function(e) { e.preventDefault(); // 阻止页面滚动 const touch = e.touches[0]; // 让图像中心与触摸点重合 img.style.left = `${touch.clientX - img.offsetWidth/2}px`; img.style.top = `${touch.clientY - img.offsetHeight/2}px`; }); f.appendChild(img); } </script> </body> </html>
关键修改说明:
- 图像定位方式调整:将
img的position从absolute改为fixed,使其脱离父方格的限制,能在整个视口范围内自由移动,同时确保left/top基于视口坐标计算。 - 初始化位置修正:通过
getBoundingClientRect()获取方格的位置,计算出方格中心坐标,将图像初始位置设置为方格中心,替代原有的transform居中方式,方便后续拖拽计算。 - 触摸事件逻辑简化:
touchstart仅负责提升图像层级,避免被其他元素遮挡;touchmove直接将图像的left设置为触摸点X坐标减去图像宽度的一半,top设置为触摸点Y坐标减去图像高度的一半,确保图像中心始终与触摸点重合。
- 代码结构优化:将棋盘元素提前添加到
body,避免循环中重复执行document.body.appendChild(d),提升性能。
内容的提问来源于stack exchange,提问作者Undefined
相关产品推荐
相关产品推荐

