如何用getComputedStyle获取绝对定位元素过渡后的left属性值
问题
点击目标元素后,如何获取left属性的正确更新值?比如应用--moved类时返回120px,未应用时返回100px。
背景
getComputedStyle可用于获取HTML元素的CSS属性值,但在使用绝对定位的元素上表现不符合预期:
- 添加/移除
--moved类后,getComputedStyle返回的是类变更前的left值 - 快速点击元素时,返回值常为小数,显示的是元素当前像素坐标而非CSS设定的固定值
示例代码
HTML
<div class="target"></div>
CSS
.target { position: absolute; top: 100px; left: 100px; width: 100px; height: 100px; background-color: red; transition: all 500ms linear; } .--moved { left: 120px; }
JavaScript
const myTarget = document.querySelector('.target'); const classForMoved = '--moved'; myTarget.addEventListener('click', () => { const doesTargetContainAdjustment = myTarget.classList.contains(classForMoved); if (doesTargetContainAdjustment === false) myTarget.classList.add(classForMoved); if (doesTargetContainAdjustment === true) myTarget.classList.remove(classForMoved); console.log(getComputedStyle(myTarget).left); });
解决方案
问题根源
- 类变更后立即取值无效:DOM类操作是同步的,但浏览器的样式重排/重绘是异步队列处理,调用
getComputedStyle时样式还未完成更新 - 过渡期间返回小数:
getComputedStyle返回的是元素实时渲染值,过渡动画执行中left是动态变化的中间值,自然不是设定的固定值
具体解决方法
方法1:用requestAnimationFrame等待样式更新
浏览器会在下次重绘前执行requestAnimationFrame回调,此时样式已完成更新,能拿到最新计算值:
const myTarget = document.querySelector('.target'); const classForMoved = '--moved'; myTarget.addEventListener('click', () => { const hasMovedClass = myTarget.classList.toggle(classForMoved); // 等待浏览器完成样式重绘后取值 requestAnimationFrame(() => { console.log(getComputedStyle(myTarget).left); }); });
方法2:直接读取CSS规则(获取原始设定值)
如果不需要实时渲染值,只想拿到CSS类中定义的固定left值,可以直接查询样式表规则:
const getCssPropertyValue = (selector, property) => { for (const sheet of document.styleSheets) { try { for (const rule of sheet.cssRules) { if (rule.selectorText === selector) { return rule.style.getPropertyValue(property); } } } catch (e) { // 跨域样式表会报错,直接跳过 continue; } } return ''; }; const myTarget = document.querySelector('.target'); const classForMoved = '--moved'; myTarget.addEventListener('click', () => { const hasMovedClass = myTarget.classList.toggle(classForMoved); const targetLeft = hasMovedClass ? getCssPropertyValue('.--moved', 'left') : getCssPropertyValue('.target', 'left'); console.log(targetLeft); });
方法3:监听transitionend获取过渡结束后的最终值
如果需要等待过渡动画完全结束后拿到最终固定值,绑定transitionend事件:
const myTarget = document.querySelector('.target'); const classForMoved = '--moved'; const handleTransitionEnd = () => { console.log('过渡结束后的left值:', getComputedStyle(myTarget).left); myTarget.removeEventListener('transitionend', handleTransitionEnd); }; myTarget.addEventListener('click', () => { myTarget.classList.toggle(classForMoved); myTarget.addEventListener('transitionend', handleTransitionEnd); });
内容的提问来源于stack exchange,提问作者myNewAccount
相关产品推荐
相关产品推荐

