html - 如果在将 div 插入 DOM 后更改其样式,为什么转换不起作用?
问题描述
代码很简单:
ground = document.getElementsByClassName('ground')[0]
item = document.createElement('div')
item.classList.add('roll')
item.style.transition = 'transform 5s linear'
item.style.transform = 'translateX(100%)';
ground.appendChild(item)
item.style.transform = 'translateX(-300px)';
.ground {
position: absolute;
width:500px;
height: 500px;
background-color: orange;
}
.roll {
position: absolute;
right: 0;
width: 100px;
height: 100px;
background-color: red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class='ground'></div>
</body>
</html>
我希望它是一个从右到左移动的红色块,因为我改变了变换的样式,它是在“过渡”中声明的属性。但是红色块只出现在'translateX(-300px)'的位置,我认为它应该结束。
解决方案
您的代码的问题是浏览器会看到您同时应用 CSS 转换样式(也就是在同一个调用堆栈中)。这会导致浏览器“短路”并确定它是真正重要的最终布局,并忽略translateX(100%)
中间的。
为了强制转换,您需要告诉浏览器您要在调用堆栈末尾执行下一次转换。这将产生强制浏览器执行第一个转换,然后执行第二个转换的效果。
在调用堆栈末尾调用某些内容的示例是使用window.setTimeout()
延迟0
:
const ground = document.getElementsByClassName('ground')[0];
const item = document.createElement('div');
item.classList.add('roll');
item.style.transition = 'transform 5s linear';
item.style.transform = 'translateX(100%)';
ground.appendChild(item);
// Mutate transform attribute at end of callstack
window.setTimeout(() => {
item.style.transform = 'translateX(-300px)';
}, 0);
.ground {
position: absolute;
width: 500px;
height: 500px;
background-color: orange;
}
.roll {
position: absolute;
right: 0;
width: 100px;
height: 100px;
background-color: red;
}
<div class='ground'></div>
如果你想要一个更现代的解决方案,你总是可以使用 async/await 机制。这将避免不必要地嵌套超时回调:
const ground = document.getElementsByClassName('ground')[0];
const item = document.createElement('div');
// Sleeper function
function sleep(duration) {
return new Promise(resolve => window.setTimeout(resolve, duration));
}
async function animate() {
item.classList.add('roll');
item.style.transition = 'transform 5s linear';
item.style.transform = 'translateX(100%)';
ground.appendChild(item);
// Sleep for 0ms (aka push operation to end of callstack)
await sleep(0);
// Mutate transform attribute at end of callstack
item.style.transform = 'translateX(-300px)';
}
animate();
.ground {
position: absolute;
width: 500px;
height: 500px;
background-color: orange;
}
.roll {
position: absolute;
right: 0;
width: 100px;
height: 100px;
background-color: red;
}
<div class='ground'></div>
推荐阅读
- excel - 将公式从 Excel 复制到 Notepad++
- javascript - 如何将删除按钮添加到脚本内的表格行中?
- java - 为什么我的 Testcontainers 测试在“等待数据库连接可用”时挂起直到超时?
- xslt-1.0 - 使用 xsl1.0 或 xslt 2.0 删除尾随零
- android - 外部 SD 卡在移除时损坏
- python - python中CNN多类图像分类的边界框预测
- asp.net - 使用通过 React GUI 触发的实体框架向 DB 添加新条目时出现重复条目
- node.js - 如何使用角度从数据库中获取数据
- asp.net-mvc - 我正在验证用户的凭据,但此函数始终被评估为 true
- java - 如何使用 JCodec 对 Java 视频进行实时编码?