在 JS 上积累过程中如何使用 CSS 过渡?(代码突然不起作用)



我已使用此代码来移动特定元素,并同时累积CSS属性(例如:lefttransition: cubic-bezier)的value。我在 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>

算法很简单:

  1. 关闭element's display以获取其当前 CSS 属性。(必需)

  2. 长度单位(%)分离到 CSS 属性值。

  3. 打开element's display

  4. 将数字this.acc添加到 CSS 属性值。

  5. 将其分配给element

以防万一,我已经检查了CSS和Javascript的最新补丁说明,但我不知道哪一个导致它不起作用。

任何提示都非常适合解决此问题。

谢谢。

这可能是由于内部优化。正在发生的事情是,浏览器正在批量更改样式并将它们全部添加在一起,即使您单独添加它们也是如此。这意味着left未转换。如果您尝试将任何属性与display: none一起转换为其他属性,也会发生同样的情况。

如果浏览器以前没有进行此优化,那么他们现在正在这样做,这就是您的代码损坏的原因。

对此有一个简单的解决方案,那就是在回调中运行stock以 setTimeout,如下所示:setTimeout(() => this.stock(S2N), 0);.这会通过稍后安排更改来选择退出优化(即使更改为 0ms,它仍会添加到队列中并且不会立即执行,因此选择退出)。您可以在下面的代码片段中看到此功能。这是最简单的解决方法。

另一种可能的解决方案是自己计算百分比,而不是设置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>

我找到了应用@EmanueleFeliziani答案的解决方案。 但它有点丑陋。

  1. 掩盖代码以阻止布尔标志,直到完成。

  2. setTimeout()'s timer设置为至少 100。除非,过渡在CTRL + MWing时不会再次起作用。

之后,它会顺利工作。

再次感谢您回答@EmanueleFeliziani

最后一件事,我尝试使用Math.floor自己计算百分比,但浏览器抛出infinity. o.o

'use strict';
class Assemble {
constructor(elem, acc, name, unit) {
this.elem = document.querySelector(elem);
this.acc = acc;
this.name= name;
this.unit = unit;
this.trigger = true;
setInterval(() => {
this.calc();
}, 1000);
}
calc() {
if (this.trigger) {
this.trigger = false;
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;
setTimeout(() => this.stock(S2N), 100);
}
}
stock(value) {
if(!this.trigger) {
console.log('test');
let digit = (value * 1) + this.acc;
this.elem.style.left = digit + this.unit;
this.trigger = true;
}
}
}
let proAssemble = new Assemble('.button', 10, 'left', '%');
* {
margin: 0;
padding: 0;
}
.button {
position: absolute;
width: 200px;
left: 0%;
background-color: purple;
transition: left 500ms;
}
<div class="button">
test
</div>

相关内容

  • 没有找到相关文章

最新更新