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

如何在touchmove事件中平稳移动绝对定位的居中元素?

解决绝对定位居中元素滑动时的坐标获取问题

问题分析

你的代码核心问题有两点:

  • 滑动时错误地将x1、y1赋值为transform的字符串数值,导致后续差值计算出现类型错误
  • 没有利用原生API直接获取元素实时坐标,而是依赖触摸点差值反向推导,逻辑易出错

解决方案

方法1:用getBoundingClientRect()实时获取坐标

这个API能直接返回元素当前相对于视口的位置信息,不管元素是否被transform修改,都能拿到准确的x、y、top、left等坐标值。

修改后的完整代码如下:

JavaScript

const swipeDiv = document.querySelector(".swipe");

swipeDiv.addEventListener("touchstart", handleTouchStart);
swipeDiv.addEventListener("touchmove", handleTouchMove);

// 记录元素初始偏移量(基于初始translate(-50%,-50%)的基础值)
let currentX = -swipeDiv.clientWidth / 2;
let currentY = -swipeDiv.clientHeight / 2;
let startTouchX, startTouchY;

function handleTouchStart(event) {
  const firstTouch = event.touches[0];
  startTouchX = firstTouch.clientX;
  startTouchY = firstTouch.clientY;
}

function handleTouchMove(event) {
  event.preventDefault();
  if (!startTouchX || !startTouchY) return;
  
  const touch = event.touches[0];
  const xDiff = touch.clientX - startTouchX;
  const yDiff = touch.clientY - startTouchY;

  // 更新元素当前偏移量
  currentX += xDiff;
  currentY += yDiff;
  
  // 应用transform样式
  this.style.transform = `translate(${currentX}px, ${currentY}px) rotate(-20deg)`;

  // 获取并打印当前元素的实时坐标
  const rect = this.getBoundingClientRect();
  console.log("当前元素视口坐标:", {
    x: rect.x,
    y: rect.y,
    top: rect.top,
    left: rect.left
  });

  // 更新起始触摸点,保证下一次滑动计算的准确性
  startTouchX = touch.clientX;
  startTouchY = touch.clientY;
}

CSS

body {
  width: 100vw;
  height: 200vh;
  margin: 0;
  padding: 0; /* 修正原代码拼写错误 */
  display: flex;
  justify-content: center;
  font-size: 1.2rem;
  background: pink;
}

.wrapper {
  position: relative;
  overflow: hidden;
  width: 200px;
  height: 150px;
  margin-top: 200px;
  background: #ccc;
}

.swipe {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-20deg);
  display: flex;
  justify-content: center;
  align-items: center;
  width: 400px;
  height: 300px;
  background: rgba(255, 0, 0, .5);
}

HTML

<div class="wrapper">
  <div class="swipe">Testing touchmove</div>
</div>

关键说明

  • getBoundingClientRect()返回的是相对于视口的坐标,如果需要相对于文档的全局坐标,可加上window.scrollX和window.scrollY(比如rect.x + window.scrollX)
  • 维护currentX、currentY变量跟踪元素偏移量,避免依赖触摸点累计差值导致的误差
  • 修正了原代码中x1、y1转字符串的错误,确保数值计算逻辑正确

额外提示

如果需要获取元素相对于父容器(.wrapper)的坐标,可通过以下方式计算:

const parentRect = document.querySelector(".wrapper").getBoundingClientRect();
const relativeX = rect.x - parentRect.x;
const relativeY = rect.y - parentRect.y;
console.log("相对于父容器的坐标:", {relativeX, relativeY});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:25:39