简体   繁体   English

循环遍历从动态生成的索引开始的数组

[英]Loop through an array starting at a dynamically-generated index

Sorry if the title doesn't accurately capture my question;对不起,如果标题没有准确地抓住我的问题; wasn't sure how to write this in a single sentence.不知道如何用一句话来写这个。

Problem description: Let's say I have an array of colors and a bunch of divs.问题描述:假设我有一个 colors 数组和一堆 div。 I want to cycle the div background color through the array colors, but also making sure each div starts at a different position in the color array.我想通过数组 colors 循环 div 背景颜色,但还要确保每个 div 从颜色数组中的不同 position 开始。

Example: my color array is [red, blue, yellow, green] .示例:我的颜色数组是[red, blue, yellow, green] The first div color starts as red , then cycles through blue , yellow , green before going back to red .第一个div颜色从red开始,然后在blueyellowgreen之间循环,然后再变回red Div2 starts as blue , then goes yellow, green, red, blue , and so on for as many div elements as I have. Div2 以blue开始,然后变为yellow, green, red, blue等,以获取尽可能多的div元素。

The two potential solutions I can imagine are:我能想象的两个潜在解决方案是:

  1. Would I have to generate a new color array for each div?我是否必须为每个 div 生成一个新的颜色数组? (maybe by adding 1 to a counter and doing a splice or push or pop operation) (也许通过在计数器上加 1 并进行拼接或推送或弹出操作)
  2. Could I loop through the original array, just starting from a different position for each div?我可以循环遍历原始数组,只是从每个 div 的不同 position 开始吗? (dynamically generate an offset based on its position - 1st div, 2nd, 3rd, etc.) (根据其 position - 1st div、2nd、3rd 等动态生成偏移量)

Are these both viable ways to solve the problem?这两种方法都是解决问题的可行方法吗?

Sounds like all you need is modulo.听起来你只需要模数。 Once you've identified the starting index for a particular element, increment the index modulo the array length.确定特定元素的起始索引后,以数组长度为模递增索引。 If the colors array is colors , then you could do something like如果 colors 数组是colors ,那么你可以做类似的事情

async function cycle(elm, index) {
  while (true) {
    elm.style.backgroundColor = colors[index];
    index = (index + 1) % colors.length;
    await delay(1000);
  }
}
cycle(someElement, 0);
// or
cycle(someOtherElement, 1);
// etc

Just for fun, this animation in CSS.只是为了好玩,这个 CSS 中的 animation。 The question is tagged as 该问题被标记为

 .color-change { --animation-duration: 5s; display: inline-block; height: 100px; width: 100px; animation: colors var(--animation-duration) steps(1, end) infinite; }.color-change:nth-child(4n+2) { animation-delay: calc(var(--animation-duration) * -.25) }.color-change:nth-child(4n+3) { animation-delay: calc(var(--animation-duration) * -.5) }.color-change:nth-child(4n+4) { animation-delay: calc(var(--animation-duration) * -.75) } @keyframes colors { from, to { background: red; } 25% { background: blue; } 50% { background: yellow; } 75% { background: green; } }
 <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div>

You do not need to generate a new array for each div, so while both of your proposed solutions could work, the second one is the better way to go.不需要为每个 div 生成一个新数组,因此虽然您提出的两种解决方案都可以工作,但第二种方法是 go 的更好方法。

When setting the initial color for each div, you simply need to select the color based off the index of the current div.为每个 div 设置初始颜色时,您只需要 select 基于当前 div 的索引的颜色。

div[index].style.backgroundColor = colors[index];

Since you can have more divs than colors you need to start from the beginning of the array once the index of the div exceeds the number of colors.由于您可以拥有比 colors 更多的 div,因此一旦 div 的索引超过 colors 的数量,您需要从数组的开头开始。 As CertainPerformance's answer shows, you can use the modulus of the index to easily "loop" the index back to the beginning.正如CertainPerformance 的答案所示,您可以使用索引的模数轻松地将索引“循环”回到开头。 So the assignment becomes:所以任务变成了:

divs[index].style.backgroundColor = colors[index % colors.length];

Once you've done the initial color assignment one way to iterate through the colors is to simply find the index of the current color and increment one, again using the modulus in order to loop through the colors.完成初始颜色分配后,一种遍历 colors 的方法是简单地找到当前颜色的索引并增加一,再次使用模数以循环通过 colors。

var currentColor = doc.style.backgroundColor;
var colorIndex = (colors.indexOf(currentColor) + 1) % colors.length;
doc.style.backgroundColor = colors[colorIndex];

Here is a complete example.这是一个完整的例子。

 var colors = ['red', 'blue', 'yellow', 'green']; function assignInitialColors() { var divs = document.getElementsByClassName("color-change"); for (var index in divs) { var colorIndex = index % colors.length; if(divs[index].style) { divs[index].style.backgroundColor = colors[colorIndex]; } } setInterval(iterateColors, 2000); } function iterateColors() { var divs = document.getElementsByClassName("color-change"); for (var index in divs) { var doc = divs[index]; var currentColor = doc.style && doc.style.backgroundColor; if (currentColor) { var colorIndex = (colors.indexOf(currentColor) + 1) % colors.length; doc.style.backgroundColor = colors[colorIndex]; } } } assignInitialColors();
 div, .color-change { min-height: 60px; min-width: 60px; margin: 5px; float: left; }
 <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div> <div class="color-change"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM