有任何关于如何重构和改进这个Javascript倒计时的想法吗?(长代码)

Any idea on how to refactor and improve this Javascript Countdown? [long code]

本文关键字:代码 倒计时 Javascript 重构 于如何 任何关      更新时间:2023-09-26

倒计时显示如下HOUR &分钟,秒示例48Hours 12MIN 02 SECONDS.

  1. 我试图修改它,使其显示2Days 0Hours 12Min 02Seconds,但是当我这样做时,代码中断。

  2. 我遇到的另一个问题是,一旦倒计时几乎完成,它显示为00 000 000。

注:代码可能看起来很长,但其中大部分都是被赋值的变量,我包含它们只是为了防止混淆。

乐趣:

function countdown(yr,m,d,hr,min,sec,id_d,url,gettimezone){
// Here I skipped some Variable assigments. That help define futurestring andd todaystring.
    //Main Variable assignments START
var dd=futurestring-todaystring;
    // futurstring - todaystring are self-explanatory, the future date - todays date.     
var dday=Math.floor(dd/(60*60*1000*24)*1);
var dhour=Math.floor((dd%(60*60*1000*24))/(60*60*1000)*1);
dday = (dday*24)+dhour; //converted days to hour
var dmin=Math.floor(((dd%(60*60*1000*24))%(60*60*1000))/(60*1000)*1);
var dsec=Math.floor((((dd%(60*60*1000*24))%(60*60*1000))%(60*1000))/1000*1);
    //Main Variable assignments END
     //Here is where it really starts.
    if(dday<=0&&dmin<=0&&dsec<=0) //I believe this is causing issue 2, this should be displaying the 00s if the countdown is over.
    {
        document.getElementById(id_de+'tot_hrs2').innerHTML='00';
        document.getElementById(id_de+'tot_mins2').innerHTML='00';
        document.getElementById(id_d+'tot_secs2').innerHTML='00';
        setTimeout("redirect_url_fn('"+url+"')",2000);
    }
    else 
    {
        if(dday<10)
         {
          dday='0'+dday;
         }
         if(dmin<10)
         {
          dmin='0'+dmin;
         }
         if(dsec<10)
         {
          dsec='0'+dsec;
         }

                    //Tried replacing dday with dhour & adding dday while
                    //Removing dday = (dday*24)+dhour; //converted days to hour
                    //But I don't get the correct countdown time in D-H-M-S format
        document.getElementById(id_de+'tot_hrs2').innerHTML=dday;
        document.getElementById(id_de+'tot_mins2').innerHTML=dmin;
        document.getElementById(id_d+'tot_secs2').innerHTML=dsec;
        setTimeout("countdown('"+year+"','"+month+"','"+day+"','"+hour+"','"+minute+"','"+second+"','"+id_de+"','"+url+"','"+tz+"')",1000);
        //setTimeout("cou("+id_d+")",1000);
        //setTimeout("redirect_url_fn('"+url+"')",2000);
                  if(dday<=0) // dday zero allowed here
             {
            document.getElementById(id_de+'tot_hrs2').innerHTML=''; 
                document.getElementById('hrs').innerHTML='';                    
             }      
    }
}

考虑您关心的是当前日期与传递给countdown的日期之间的差值。实际的日期对象不是必需的——当然日期字符串也不是必需的。您可以将所有的日期字符串化、解析和减法压缩为两行:

var future = Date.UTC(year, month, day, hour, min, sec) - (gettimezone * 1000 * 60 * 60);
var ms_til_then = future - Date.now();

(假设gettimezone是UTC的小时数。EST将是-5,例如)

现在,对于你的代码:

function countdown(yr,m,d,hr,min,sec,id_de,url,tz){
    // You had 3 sets of vars that were all equal and meant the exact same thing.
    // Those are now gone.
    // i hate repetitive math with a thug passion.
    // use these instead of 1000*60*60*24 and whatever all over the place.
    var MS_PER_SEC  = 1000,
        MS_PER_MIN  = MS_PER_SEC * 60,
        MS_PER_HOUR = MS_PER_MIN * 60,
        MS_PER_DAY  = MS_PER_HOUR * 24;
    // The two lines i mentioned above
    var future_time = Date.UTC(yr, m-1, d, hr, min, sec) - (tz * MS_PER_HOUR); 
    var dd = future_time - Date.now();
    // The dhour, dmin, dsec etc stuff can wait a bit
    // Here, we care if the "future time" is past the current time, right?
    // We already have a number that represents the difference between the two.
    // If dd <= 0, then the time has passed.
    if(dd <= 0)
    {
        // Note, we're doing the same thing with the elements as we would if dd==0.
        // Let's not repeat ourselves; the only major difference between the two is
        // what we set for the callback and when it happens.
        // So here, let's let dd=0 and let both branches do the same thing with the
        // date elements.
        dd = 0;
        // Remind me to smack whoever taught you this was right.
        // setTimeout("redirect_url_fn('"+url+"')",2000);
        // Instead, we specify the function directly, saving parsing and avoiding the
        // dirty looks we get when we eval stuff.
        // Note we can pass params to the function; we just put them after the timeout.
        setTimeout(redirect_url_fn, 2000, url);
    }
    else 
    {
        // Again...no need to compose a string to call ourselves again.
        // If we wanted to get fancy, we could wrap most of the meat of this function
        // up in a closure, and call it, and not have to keep passing all these params.
        // But that's spiff for another time.
        setTimeout(countdown, 1000, yr, m, d, hr, min, sec, id_de, url, tz);
    }
    // Moving all this closer to where it's used.
    var dday=Math.floor(dd/MS_PER_DAY);
    var dhour=Math.floor((dd%MS_PER_DAY)/MS_PER_HOUR);
    // math time: if a and b are positive, and a is divisible by b, then ((n%a)%b)==n%b
    // Meaning: We can simplify this crap.
    var dmin=Math.floor((dd % MS_PER_HOUR) / MS_PER_MIN);
    var dsec=Math.floor((dd % MS_PER_MIN) / MS_PER_SEC);
    // I had to fix this; it was bugging me.  When you have a variable named
    // dDAY that contains HOURS, your variable names are lying to you.
    dhour = (dday*24)+dhour; // Converting days+hours to just hours
    if(dhour<10)
    {
        dhour='0'+dhour;
    }
    if(dmin<10)
    {
        dmin='0'+dmin;
    }
    if(dsec<10)
    {
        dsec='0'+dsec;
    }
    document.getElementById(id_de+'tot_hrs2').innerHTML=dhour;
    document.getElementById(id_de+'tot_mins2').innerHTML=dmin;
    document.getElementById(id_de+'tot_secs2').innerHTML=dsec;
    // Don't need <= here; if we're in this part of the code, dhour is not negative
    if(dhour==0)
    {
        // hide hours and label
        document.getElementById(id_de+'tot_hrs2').innerHTML=''; 
        document.getElementById('hrs').innerHTML='';
    }
}
// for example, to count down to new years...
countdown(2012, 1, 1, 0, 0, 0, '', 'http://happynewyear.com', -5);

我还建议countdown采用Date对象而不是一堆日期部分。但现在,我已经完成了更改。

好了,现在可以读了,让我们看看这些问题。

如果您想显示天数,那么您需要去掉表示dhour = (dday * 24) + dhour;的行。这样就把天+小时变成了小时。您还需要添加一行来设置元素的内容,就像您设置小时、分钟和秒一样。

还有,看到末尾那一节开始的if (dhour == 0)…?这需要删除或更改为dday(代码需要更改为设置日元素而不是小时元素)。

哦…看起来我可能已经不小心修复了第二个问题:P