You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

触摸拖拽事件中保持图像居中的实现问题

解决方案:触摸拖拽时让图像中心对齐触摸点

以下是修改后的完整代码,实现触摸图像任意位置时,图像中心自动跳转到触摸点,并在拖拽过程中保持中心跟随触摸点移动:

<!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>

关键修改说明:

  1. 图像定位方式调整:将img的position从absolute改为fixed,使其脱离父方格的限制,能在整个视口范围内自由移动,同时确保left/top基于视口坐标计算。
  2. 初始化位置修正:通过getBoundingClientRect()获取方格的位置,计算出方格中心坐标,将图像初始位置设置为方格中心,替代原有的transform居中方式,方便后续拖拽计算。
  3. 触摸事件逻辑简化:
    • touchstart仅负责提升图像层级,避免被其他元素遮挡;
    • touchmove直接将图像的left设置为触摸点X坐标减去图像宽度的一半,top设置为触摸点Y坐标减去图像高度的一半,确保图像中心始终与触摸点重合。
  4. 代码结构优化:将棋盘元素提前添加到body,避免循环中重复执行document.body.appendChild(d),提升性能。

内容的提问来源于stack exchange,提问作者Undefined

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 17:35:56