嵌套用于同时更新3个变量的循环



我四处寻找,但没有找到解决方案。

我想打印出这个之间的"插值"点:

.card.ani25 {
bottom: 72%;
left:85%;
}

这个:

.card.ani49 {
bottom: 46%;
left: 46%;
}

基本上,我试图同时更新CSS中的所有数值。一次更新一个值是有效的,但在这种情况下没有用。到目前为止,我已经尝试了,好吧,脑海中浮现的一切,包括触发一些无限循环,但这就是"稳定"的:-)

for (var i = 25; i < 50; i++){
for (var j = 72; j >=46; j-=2){
for (var k = 85; k >=46; k-=3){
t.innerHTML = '.card.ani' + i + ' {' + '<br>' + 'bottom: ' + j + '%;' + '<br>' + 'left: ' + k + '%;' + '<br>' + '}';
}
}
}

这只打印出最后一次迭代,如图所示:

http://codepen.io/damianocel/pen/ZLEXOR

如果我在"innerHTML2"后面加上一个+=,它就会爆炸,屏幕冻结,就像一个无限循环

我知道,最外面的循环首先运行,然后下一个内部循环第二次运行多次,但我从未见过有3个变量的情况。老实说,我也不知道两个变量的解。

如果之前有人问过这个问题,谢谢,非常抱歉。

问题是通过重新分配innerHTML来更改HTML的操作很慢。当您使用+=时,它每次都会重写HTML,这就是导致它速度减慢的原因。也就是说,它仍然有效,一种更快的方法是使用一个变量来保存字符串并更新该变量。然后在最后将t.innerHTML的值分配给该字符串:

var t = document.getElementById('target');
var str = "";
for (var i = 25; i < 50; i++){
for (var j = 72; j >=46; j-=2){
for (var k = 85; k >=46; k-=3){
str += '.card.ani' + i + ' {' + '<br>' + 'bottom: ' + j + '%;' + '<br>' + 'left: ' + k + '%;' + '<br>' + '}';
}
}
}
t.innerHTML = str;

编辑

澄清后,您似乎只想要一个循环,并在该循环中每次更新变量。在这种情况下,你可以做一些类似的事情:

var t = document.getElementById('target');
var str = "";
for (var i = 25, j = 72, k = 85; i < 50 && j >=46 && k >=46; i++, j-=2, k-=3){
str += '.card.ani' + i + ' {' + '<br>' + 'bottom: ' + j + '%;' + '<br>' + 'left: ' + k + '%;' + '<br>' + '}';
}
t.innerHTML = str;

对于For循环for(x;y;z)中的每个部分,您可以使用逗号来生成许多语句。因此,在第一节中,您可以定义3个变量,在最后一节中更新3个变量。只要满足所有这些条件,中间部分就会运行循环,当单个条件失败时,它就会停止。

注意:如果您希望||()继续运行,只要其中一个条件为真,就可以使用它。

代码笔(单循环)

代码笔

我会提倡一种非常不同的方法。

我认为这是许多不同的范围,需要并行设置动画。所以我想要一个知道如何做到这一点的函数。

const rangeFns = (...configs) => fn => val => 
fn.apply(null, configs.map(cfg => (cfg.end - cfg.start) * val + cfg.start))

这需要一组范围描述,并返回一个函数,该函数接受每个范围都有一个参数的自定义函数,最后返回一个接受0到1之间的数字的简单函数,返回自定义函数的结果,并为各个参数提供每个范围的插值。这有点难,但我认为它很容易使用:

const anim = rangeFns(
{start: 25, end: 49},
{start: 72, end: 46},
{start: 85, end: 46}
)((ani, bottom, left) => `
.card.ani${Math.round(ani)} {
bottom: ${bottom}%;
left: ${left};
}`
);

如果你用值0、0.25、0.5、0.75和1运行这个,你会得到以下结果:

.card.ani25 {
bottom: 72%;
left: 85;
}
.card.ani31 {
bottom: 65.5%;
left: 75.25;
}
.card.ani37 {
bottom: 59%;
left: 65.5;
}
.card.ani43 {
bottom: 52.5%;
left: 55.75;
}
.card.ani49 {
bottom: 46%;
left: 46;
}

(显然,如果需要的话,您可以对bottomleft添加舍入。)

然后,您可以在动画中使用它,通过传递从开始和结束时间计算的值。

在我看来,这样做的好处是更明确。它使范围更具声明性,并使使用结果的函数更加直观。

此版本可在Codepen上获得。

更新

一个稍微好一点的版本是使用数组而不是对象。(我最初有一些额外的参数,但没有必要。我没有注意到删除它们可以进行很好的清理。)

const multiRange = (...ranges) => fn => val => 
fn.apply(null, ranges.map(range => (range[1] - range[0]) * val + range[0]))
const anim = multiRange([25, 49], [72, 46], [85, 46])((ani, bottom, left) => `
.card.ani${Math.round(ani)} {
bottom: ${bottom}%;
left: ${left};
}`
);

我觉得这个读起来更好。

此版本也在Codepen上。

最新更新