使用getBoundingClientRect()调整绝对定位元素位置的问题
问题解决:小方块滑动到选中答案中心的位置修正
问题根源
当前代码的错误在于:
translate的偏移值计算未考虑.box自身尺寸,导致方块左上角对齐按钮中心,而非方块中心与按钮中心对齐。- 直接使用目标元素相对于容器的绝对位置作为偏移量,忽略了
transform是基于元素自身初始位置的相对偏移特性。
修正方案
- 启用
box.getBoundingClientRect()获取方块自身尺寸,计算偏移时减去方块宽高的一半,确保中心对齐。 - 每次点击直接计算目标位置的正确相对偏移,无需累计之前的偏移(
transform会覆盖之前的值)。 - 保留CSS定义的初始位置,第一次滑动从该位置出发。
修正后的完整代码
JavaScript
const { useRef } = React; const ANSWERS = ["answer 1", "answer 2", "answer 3", "answer 4"]; const App = () => { const boxRef = useRef(null); const handleSelectAnswer = (answer) => { const selectedAnswerElement = document.querySelector( `[data-answer="${answer}"]` ); const box = boxRef.current; const answersContainer = document.querySelector(".answers"); if (selectedAnswerElement && box && answersContainer) { const selectedAnswerRect = selectedAnswerElement.getBoundingClientRect(); const containerRect = answersContainer.getBoundingClientRect(); const boxRect = box.getBoundingClientRect(); // 启用该行获取方块尺寸 // 计算目标位置相对于容器的坐标 const targetX = selectedAnswerRect.left - containerRect.left + selectedAnswerRect.width / 2; const targetY = selectedAnswerRect.top - containerRect.top + selectedAnswerRect.height / 2; // 计算方块需要偏移的距离:目标坐标 - 方块自身中心的初始位置 const offsetX = targetX - boxRect.width / 2; const offsetY = targetY - boxRect.height / 2; box.style.transform = `translate(${offsetX}px, ${offsetY}px)`; } }; return ( <div className="answers"> {ANSWERS.map((answer) => ( <button key={answer} data-answer={answer} onClick={() => handleSelectAnswer(answer)} > {answer} </button> ))} <div className="box" ref={boxRef} /> </div> ); }; ReactDOM.render(<App />, document.getElementById("root"));
CSS
.answers { margin: 0 auto; display: grid; grid-template-columns: repeat(2, 270px); grid-template-rows: repeat(2, 1fr); column-gap: 1rem; row-gap: 1rem; color: white; position: relative; width: max-content; } .answers button { height: 150px; } .box { width: 50px; height: 50px; background-color: lightblue; position: absolute; bottom: -25%; left: 0; right: 0; margin: 0 auto; transition: all 0.5s ease; z-index: 999; }
HTML
<div id="root"> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"></script> </div>
关键说明
boxRect.width / 2和boxRect.height / 2:减去方块自身一半的尺寸,确保方块中心与按钮中心对齐。transform每次都会覆盖之前的偏移值,因此无需跟踪之前的位置,直接计算目标位置即可满足“在选中答案间切换位置”的要求。- 初始位置由CSS定义,第一次点击时
transform会从该位置平滑过渡到目标位置,符合需求。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

