javascript - 在 JS 上积累时如何使用 CSS 过渡?(代码突然不起作用)
问题描述
我一直在使用此代码来移动特定元素,并同时累积value
CSS 属性(例如left
:)transition: cubic-bezier
。我在 2 到 3 天前检查过此代码是否有效,但今天突然,transition
由于未知原因,该代码不再有效。
这是代码:
'use strict';
class Assemble {
constructor(elem, acc, name, unit) {
this.elem = document.querySelector(elem);
this.acc = acc;
this.name= name;
this.unit = unit;
}
calc() {
let displayOn = this.elem.style.display;
this.elem.style.display = 'none';
let currentProp = window.getComputedStyle(this.elem, null).getPropertyValue(this.name),
S2N = parseInt(currentProp, 10);
this.elem.style.display = displayOn;
this.stock(S2N);
}
stock(value) {
let digit = (value * 1) + this.acc;
this.elem.style.left = digit + this.unit;
console.log(this.elem.style.left);
}
}
let proAssemble = new Assemble('.button', 10, 'left', '%');
setInterval(() => {
proAssemble.calc();
}, 1500)
* {
margin: 0;
padding: 0;
}
.button {
position: absolute;
width: 200px;
left: 10%;
background-color: purple;
transition: left 1000ms;
}
<div class="button">
test
</div>
算法很简单:
关闭
element's display
以获取其当前的 CSS 属性。(必要的)将长度单位(
%
)分离到 CSS 属性值。打开
element's display
.将数字添加
this.acc
到 CSS 属性值。将其分配给
element
.
以防万一,我已经检查了CSS和Javascript的最新补丁说明,但我不知道是哪一个导致它不起作用。
任何提示都可以很好地解决这个问题。
谢谢。
解决方案
这可能是由于内部优化。正在发生的事情是浏览器正在批量更改样式并将它们全部添加在一起,即使您单独添加它们也是如此。这意味着left
没有被转换。如果您尝试将任何属性与其他属性一起转换,也会发生同样的情况display: none
。
如果浏览器之前没有进行此优化,他们现在正在这样做,这就是您的代码被破坏的原因。
对此有一个简单的解决方案,即stock
在 setTimeout 的回调中运行,如下所示setTimeout(() => this.stock(S2N), 0);
:这通过在以后安排更改来选择您退出优化(即使它是 0 毫秒,它仍会添加到队列中并且不会立即执行,因此选择退出)。您可以在下面的代码段中看到这一点。这是最简单的修复。
另一种可能的解决方案是自己计算百分比,而不是设置display: none
来获取百分比值。据我了解,这种行为没有很好的定义,将来可能会改变。您可以改为计算左值的百分比,如下所示:
Math.floor(window.innerWidth / parseInt(currentProp, 10))
您可以在Assemble
对象的实例化期间执行此操作,或者在类中创建某种逻辑来检测是否unit
为百分比。
最后一句警告:转换left
效率相当低。尝试转换transform: translateX(value)
属性。渲染性能要好得多。
'use strict';
class Assemble {
constructor(elem, acc, name, unit) {
this.elem = document.querySelector(elem);
this.acc = acc;
this.name= name;
this.unit = unit;
}
calc() {
let displayOn = this.elem.style.display;
this.elem.style.display = 'none';
let currentProp = window.getComputedStyle(this.elem, null).getPropertyValue(this.name),
S2N = parseInt(currentProp, 10);
this.elem.style.display = displayOn;
if (S2N < 100) {
setTimeout(() => this.stock(S2N), 0);
}
}
stock(value) {
let digit = (value * 1) + this.acc;
this.elem.style.left = digit + this.unit;
this.elem.addEventListener('transitionend', this.calc.bind(this), {once: true})
console.log(this.elem.style.left);
}
}
let proAssemble = new Assemble('.button', 10, 'left', '%');
proAssemble.calc();
* {
margin: 0;
padding: 0;
}
.button {
position: absolute;
width: 200px;
left: 0;
background-color: purple;
transition: left 1000ms;
}
<div class="button">
test
</div>
推荐阅读
- java - Java:set.remove() 方法不会从 Set 中删除对象
- node.js - 端口 443 不适用于 https 节点快递
- javascript - 如何使用 javascript 处理我的 firebase 实时数据库中的未命名节点?
- c++ - 从 C++ 中的用户定义函数返回多数组的结构
- neo4j - 如何从 Bolt Driver 获取 GraphDatabaseService 实例
- go - golang 将文件发布到烧瓶服务器
- angular - 使用 --configuration 运行 ionic serve 时,Ionic live reload 无法正常工作
- excel - UDF 函数不显示结果
- python - 新任务的 RoBERTa 微调中的 from_logits=True 与 from_logits=False
- javascript - 在 beforeSession 挂钩中向 edgeOptions 添加功能时出现 WebdriverIO 错误