实际上,我是通过ajax从数据库中检索一些数据的,在检索数据时,我使用javascript在html中创建了一些动态元素。我在容器中创建了动态行,并在该行中创建了一个动态div,其类为“ col-md-4”,它是父行的子级,这意味着可以有至少3个class =“ col-md-4的动态divs在动态行中。为此,在AJAX的obj.success函数中使用了一个循环。使用循环的目的是在动态行中制作3个动态元素。如果不使用循环,那么新行将只有一格的col-md-4类 现在的问题是我从数据库中检索了一些时间,然后花了当前时间,我得到了两个tme的差,然后使用一个函数来运行时间。所有这些都是循环。现在的问题是计时器仅针对行中的最后一个元素运行 我在另一种情况下使用计时器,但那没有问题,因为在该情况下没有使用循环
var ajax = prompt('Confirm demo or paste AJAX data', '[ {"id":1}, {"id":2}, {"id":3}, {"id":4}, {"id":5}]');
display(ajax);
function display(response) {
var n=1;
var times = ["2019-09-19 12:59","2019-09-27 12:59","2019-12-19 12:59","2019-11-19 12:59","2019-10-19 12:59"];
var time=new Date().toLocaleTimeString('en-GB');
var res = time.slice(0,-3);
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0');
var yyyy = today.getFullYear();
today = yyyy + '-' + mm + '-' + dd;
var current=today+" "+res;
// alert(current);
var data = JSON.parse(response);
if(data.length) {
for(var i=0;i<data.length;i++) {
var parent= document.getElementsByClassName('carousel')[0];
var row1= document.createElement("div");
row1.setAttribute("class", "row");
row1.setAttribute("id", "row"+n);
parent.appendChild(row1);
var crow1;
for(var j=0;j<3 && i+j < data.length;j++) {
crow1 = document.createElement("div");
crow1.setAttribute("class", "col-md-4");
crow1.setAttribute("id", data[i+j].id);
crow1.innerText = "data" + (i+j)+" ";
row1.appendChild(crow1);
var distance = (new Date(times[0])).getTime() - (new Date(current)).getTime();
var lmn = Math.floor(Math.random() *999999999999);
var timer = document.createElement("h");
timer.setAttribute("id",lmn);
crow1.appendChild(timer);
var x = setInterval(function() {
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById(lmn).innerHTML =days + "days " + hours + "hours " + minutes + "mins " + seconds + "secs ";
distance -= 1000;
if (distance < 0) {
clearInterval(x);
document.getElementById(lmn).innerHTML = "¡El tiempo de partida ha comenzado!";
}
}, 1000);
}
i += 3-1;
n++;
}
}
}
DIV.col-md-4 {
display: inline;
background-color: #FF0080;
margin: 5px;
}
.row {
display: block;
background-color: #80E080;
padding: 3px;
}
<div class="carousel">
</div>
为什么只有最后一个元素显示计时器
答案 0 :(得分:1)
您遇到的行为是同步工作流问题中的经典异步功能。在您的 setInterval 回调中,您使用的是值 lmn 。到回调函数访问此变量时,代码流将在循环中循环,并且 lmn 将具有最大循环索引值。
因此,要解决此问题,请将您的异步函数封装在一个闭包函数调用中,然后将在该回调中使用的变量(在async方法外部设置)作为该闭包调用的参数发送。检查下面的代码示例,我已通过闭包调用对其进行了更新。
要了解它的工作原理,请在调试控制台中的一个检查点上放置您在异步回调中使用 lmn 变量的位置(带有或不带有闭包调用)。
要了解有关闭包的更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
var ajax = prompt('Confirm demo or paste AJAX data', '[ {"id":1}, {"id":2}, {"id":3}, {"id":4}, {"id":5}]');
display(ajax);
function display(response) {
var n = 1;
var times = ["2019-09-19 12:59", "2019-09-27 12:59", "2019-12-19 12:59", "2019-11-19 12:59", "2019-10-19 12:59"];
var time = new Date().toLocaleTimeString('en-GB');
var res = time.slice(0, -3);
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0');
var yyyy = today.getFullYear();
today = yyyy + '-' + mm + '-' + dd;
var current = today + " " + res;
// alert(current);
var data = JSON.parse(response);
if (data.length) {
for (var i = 0; i < data.length; i++) {
var parent = document.getElementsByClassName('carousel')[0];
var row1 = document.createElement("div");
row1.setAttribute("class", "row");
row1.setAttribute("id", "row" + n);
parent.appendChild(row1);
var crow1;
for (var j = 0; j < 3 && i + j < data.length; j++) {
crow1 = document.createElement("div");
crow1.setAttribute("class", "col-md-4");
crow1.setAttribute("id", data[i + j].id);
crow1.innerText = "data" + (i + j) + " ";
row1.appendChild(crow1);
var distance = (new Date(times[0])).getTime() - (new Date(current)).getTime();
var lmn = Math.floor(Math.random() * 999999999999);
var timer = document.createElement("h");
timer.setAttribute("id", lmn);
crow1.appendChild(timer);
(function(l, d){
var x = setInterval(function() {
var days = Math.floor(d / (1000 * 60 * 60 * 24));
var hours = Math.floor((d % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((d % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((d % (1000 * 60)) / 1000);
document.getElementById(l).innerHTML = days + "days " + hours + "hours " + minutes + "mins " + seconds + "secs ";
d -= 1000;
if (d < 0) {
clearInterval(x);
document.getElementById(l).innerHTML = "¡El tiempo de partida ha comenzado!";
}
}, 1000);
})(lmn, distance); // This is called a closure function, use this when you are using async methods in synchronous code blocks
}
i += 3 - 1;
n++;
}
}
}
DIV.col-md-4 {
display: inline;
background-color: #FF0080;
margin: 5px;
}
.row {
display: block;
background-color: #80E080;
padding: 3px;
}
<div class="carousel">
</div>