Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
126 views
in Technique[技术] by (71.8m points)

jquery - Manage the timer made in a dynamic element in JavaScript

Actually I am retrieving some data from database through AJAX and on retrieval of data i made some dynamic element in HTML using JavaScript. I made dynamic row in a container and in that row i making a dynamic div whose class is "col-md-4" which is child of parent row it means there can be at least 3 dynamic divs of class="col-md-4" in a dynamic row. For this purpose is used a loop in the obj.success function of AJAX. The purpose of using loop to make 3 dynamic elements in dynamic row. If don't use loop then the new row will only have one div of class col-md-4.

Now the problem I am retrieving some time from database and then taking current time I am getting the difference of both tme and then use a function to run the time. All this is loop. Now problem is timer is running only for last element in row. I use the timer in another scenario, but for that there is no problem because there is no loop used in that scenario.

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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The behavior you are experiencing is a classic async function in a synchronous workflow issue. Inside your setInterval's callback, you are using the value lmn. By the time this variable is accessed by the callback function, the code flow would have cycled through the loops and lmn will be left with the max loop index value.

So to tackle this you enclose your async function in a closure function call and send the variable (that is set outside the async method) that is being used in that call back as a parameter to that closure call. Check the code sample below, I have updated it with a closure call.

To understand how this works better, place a checkpoint in your debug console at the point where you are using lmn variable in the async callback, with and without the closure call.

To know more about closures : 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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...