javascript - javascript loop through dynamic array of elements, get values then use values as interval to set timer countdown
问题描述
I am making a timer that will use dynamically entered information to then display a count down timer for each entry. The timer will iterate over different values within a nodeList. These values will always be numeric values,
Here is an example: 20, 7, 20, 7, 20, 7, 90, 20, 7, 20, 7, 20, 7, 90
These values represent blocks of seconds. So 20 seconds, then 7 seconds, then 20 seconds, then 7, etc...
I want to iterate over this list, get the values, then assign there values as seconds and loop through the list pausing for the defined time each time a new value is looped. I will be adding further nested code within this loop that counts down a timer set by each value accordingly, but I am not worried about the count down yet, just getting the iteration of each block of seconds to count down properly atm.
So using the example list above, I fire first value (20) immediately, pause 20 seconds(its value in seconds), then fire the next value (7), pause 7 seconds, then fire the next value pause for its value in seconds, so on until the entire list has expired.
NOTE: This info could always be different per form submission so the code must be dynamic in nature.
Here is the closest I have come in my attempt so far.
First, I have gathered the values using Javascript:
const span = document.querySelectorAll('.selector');
span
--> represents input entries run through various foreach loops in php coming from different entries, all with the class value of .selector
inserted in each corresponding input tag. The forming of iteration over the list will always be indexed properly in time for looping through the values as I have described.
This gives me the node list.
I gather the values in a foreach loop using .textContent
, then I set an interval as a variable, get the value of the next sibling, run conditionals to set the interval, then check the firing of the loop for consistency. See my snippit below
span.forEach(function(value){
const data = value.textContent;
// Now that I have the nodelist values I run them through `setInterval`
let delay = setInterval(engine => {
const { value, set } = engine.next()
if (set) {
clearInterval(delay)
} else {
const values = value.textContent;
console.log('firing delay -> ' + values);
}
}, data * 1000, span[Symbol.iterator]())
})
The delay fires, but it is inconsistent and is not in time with proper seconds count down. I am not opposed to using a different method to get this achieved as I am a novice at JS and still learning how it works really. Any assistance would be greatly appreciated!
Again, I want to iterate over the nodelist, get its values, use those values as blocks of seconds, loop through the list pausing for each value as seconds, then moving to the next value until the list is completed.
UPDATE May 4th, 2020: Using Cedrics updated reduce code I am able to get the dynamic timeout working to display each iteration through the node list using its set value as seconds, then count down those seconds individually.
const spans = [...document.querySelectorAll('.selector')];
const timerEl = document.getElementById('timer');
const count = spans.length;
function countDown(secs,elem){
const timerEl = document.getElementById(elem);
timerEl.innerHTML = `${secs}`;
if(secs === 1){
clearTimeout(timer);
return timer;
}
secs--;
var timer = setTimeout('countDown('+secs+',"'+elem+'")',1000);
}
let i = 0;
spans.reduce((totalDelay, span) => {
setTimeout(() => {
const circuits = document.querySelectorAll('.selector');
const circuit = circuits[i].innerText;
let alt = circuits[i].attributes[0].textContent;
let time = delay;
console.log(alt)
console.log(`${circuit} -> ${delay}`);
console.log(`${i + 1} of ${count}`);
//need logic to figure out if node is last item in list then display finished
countDown(delay,"timer");
i++;
}, 1000 * totalDelay);
const delay = parseInt(span.textContent);
totalDelay += delay;
return totalDelay;
}, 0);
<span alt="Workout" class="selector">5</span>
<span alt="Break" class="selector">3</span>
<span alt="Workout" class="selector">5</span>
<span alt="Break" class="selector">3</span>
<span alt="Workout" class="selector">5</span>
<span alt="Break" class="selector">3</span>
<span alt="Cool Down" class="selector">10</span>
<span alt="Workout" class="selector">5</span>
<span alt="Break" class="selector">3</span>
<span alt="Workout" class="selector">5</span>
<span alt="Break" class="selector">3</span>
<span alt="Workout" class="selector">5</span>
<span alt="Break" class="selector">3</span>
<span alt="Cool Down" class="selector">10</span>
<div id="timer"></div>
解决方案
如果我理解正确并且如果我重新使用您的示例,您想在 20 秒后执行一些代码,然后在 7 秒后,然后 20 秒......等等。
我建议setTimeout
为每个跨度使用一个。它们都在同一时间开始。第一个使用 20 秒的延迟,第二个使用 27 秒的延迟(前一个 20 秒setTimeout
+ 7 秒),第三个使用 47 秒的延迟(前一个setTimeout
+ 20 秒的 27 秒)......你'我明白了。
我用来reduce
记录之前的延迟。
const spans = [...document.querySelectorAll('.selector')];
spans.reduce((totalDelay, span) => {
setTimeout(() => {
console.log(`firing delay -> ${delay}`);
}, 1000 * totalDelay);
const delay = parseInt(span.textContent);
totalDelay += delay;
return totalDelay;
}, 0);
<span class="selector">20</span>
<span class="selector">7</span>
<span class="selector">20</span>
<span class="selector">7</span>
<span class="selector">20</span>
<span class="selector">7</span>
<span class="selector">90</span>
<span class="selector">20</span>
<span class="selector">7</span>
<span class="selector">20</span>
<span class="selector">7</span>
<span class="selector">20</span>
<span class="selector">7</span>
<span class="selector">90</span>
推荐阅读
- python - python从apsx下载图片,验证码OCR
- javascript - 在 wavesurfer.js 和 Web Audio API 处理后下载结果 mp3 文件
- python - python日期str解析
- python - 我想通过迁移学习创建回归模型,但出现错误
- android - 我的颤振应用程序仅在调试模式下运行(USB 电缆)并且在我的设备中看不到它
- r - 无法连接到 rstudio 服务器
- c# - “图像”不包含“图像”的定义
- tkinter - 如何在鼠标悬停时修改标签面板颜色
- javascript - 如何获取带有标签的 HTML 元素文本
- c - 如何在没有strcmp的情况下比较指向字符串的指针?