【问题标题】:Change countdown when refresh the page?刷新页面时更改倒计时?
【发布时间】:2014-05-24 14:13:33
【问题描述】:

我有自己的网店,主页上有很多倒计时的产品。

那么问题是什么? 问题是,当我在主页上有很多 javascripts 时,broser 会冻结,变慢。

我怎么知道这是一个 javascript 问题?我尝试在浏览器上禁用 javascript,我的网站运行正常。

/*!
 *
 * Brian2000: BK_Countdown v1.1
 * AKA: Brian's jQuery Robust Date/Time Countdown
 * http://brian2000.com
 *
 * Copyright 2012-2013, Brian Kennedy
 * Licensed under the GPL Version 3 license
 * http://www.gnu.org/licenses/gpl-3.0.en.html
 *
 * Date: Wed Jan 9 2013 2:54PM EST  
 *
 * You can't remove this part, and if you make changes or improve things, please keep me informed.
 * Thank you, enjoy, and support Open Source!
 */

/*
    This portion explains how to use the counter, I recomend not deleting it either ;-)

    VARS [required]
    ------------------------------------------------
    container: ID of Element for counter
    targetDate: MM/DD/YYYY
    targetTime: HH:MM:SS (0-23 Hour) [seconds are optional]

    OPTIONS:
    ------------------------------------------------
    order: format/output order 
            order: 1 = Label + Spacer + Value
            order: 2 = Value + Spacer + Label (reverse from order 1)
    spacer: text/string seperator between label and value   
    element: html element for label and value containers (default is span)
    end: Message to display when date has passed
    dayOf: Message to display on day of counter expiration


*/
function BK_CountDown(container, targetDate, targetTime, opts) {
    /////////////////////////////////////////////////////
    //vars
    this.opts = opts;
    this.complete = false; //for exiting interval
    this.container = container; //target

    DArray = targetDate.split('/'); 
    this.targetDate = DArray[0] + '/' + DArray[1] + '/' + DArray[2];

    TArray = targetTime.split(':');
    this.targetHour = TArray[0]; //hr
    this.targetMin = TArray[1]; //min
    if (typeof TArray[2] == 'undefined') { //sec
      this.targetSec = 0;
    }else{
        this.targetSec = TArray[2];
    }   
    /////////////////////////////////////////////////////
    // options
    var defaults = {
        'order'     :       "1",
        'spacer'    :       ':',
        'element'   :       'span',
        'end'       :       "Deal is ended!",
        'dayOf'     :       "Deal is ended!"
    }
    if(typeof this.opts != "undefined") { //if options were assigned...
        for(var i in defaults) { //assign defaults for unchanged opts
            if(typeof this.opts[i] == "undefined") {
                this.opts[i] = defaults[i];
            }
        }
    }else{ //no options were assigned
        this.opts = defaults;
    }
    /////////////////////////////////////////////////////


    /////////////////////////////////////////////////////
    ////////  assembly                  
    /////////////////////////////////////////////////////
    s = this.opts['spacer'];
    this.c = container.substring(1);
    e = this.opts['element'];
    if(this.opts['order'] == 2){
    //reverse assembly
        $(container).append('<' + e + ' id="' + this.c + '_count_days" class="count_days"></' + e + '>');       
        $(container).append('<' + e + ' id="' + this.c + '_txt_days" class="txt_days">' + s + ' Days</' + e + '>');
        $(container).append('<' + e + ' id="' + this.c + '_count_hours" class="count_hours"></' + e + '>');     
        $(container).append('<' + e + ' id="' + this.c + '_txt_hours" class="txt_hours">' + s + ' :</' + e + '>');
        $(container).append('<' + e + ' id="' + this.c + '_count_min" class="count_min"></' + e + '>');     
        $(container).append('<' + e + ' id="' + this.c + '_txt_min" class="txt_min">' + s + ' :</' + e + '>');

    }
    else{
    //default assembly
        $(container).append('<' + e + ' id="' + this.c + '_txt_days" class="txt_days">Days ' + s + '</' + e + '>');     
        $(container).append('<' + e + ' id="' + this.c + '_count_days" class="count_days"></' + e + '>');
        $(container).append('<' + e + ' id="' + this.c + '_txt_hours" class="txt_hours">Hours ' + s + '</' + e + '>');      
        $(container).append('<' + e + ' id="' + this.c + '_count_hours" class="count_hours"></' + e + '>');
        $(container).append('<' + e + ' id="' + this.c + '_txt_min" class="txt_min">Minutes ' + s + '</' + e + '>');        
        $(container).append('<' + e + ' id="' + this.c + '_count_min" class="count_min"></' + e + '>');

    }
    /////////////////////////////////////////////////////
    /////////////////////////////////////////////////////
    ////////  Count Update function                 
    this.count_update = function count_update(){

        date = new Date(); //NOW
        targetDate = new Date(this.targetDate);
        targetDate.setHours(this.targetHour);
        targetDate.setMinutes(this.targetMin);
        targetDate.setSeconds(this.targetSec);

        var UDate =  Math.round(date.getTime()/1000);
        var UTargetDate =  Math.round(targetDate.getTime()/1000);

        differance = UTargetDate - UDate;

        days=Math.floor(differance/(60*60*24)*1);
        hours=Math.floor((differance%(60*60*24))/(60*60)*1);
        minutes=Math.floor(((differance%(60*60*24))%(60*60))/(60)*1);
        seconds=Math.floor((((differance%(60*60*24))%(60*60))%(60))*1);

        //if range is 0 don't display range
        //days
        if(days <= 0){$(this.container + '_count_days').remove();$(this.container + '_txt_days').remove();}
        else{$(this.container + '_count_days').text(days);}
        //hours
        if(days <= 0 && hours <= 0){$(this.container + '_count_hours').remove();$(this.container + '_txt_hours').remove();}
        else{$(this.container + '_count_hours').text(hours);}
        //min
        if(days <= 0 && hours <= 0 && minutes <= 0){$(this.container + '_count_min').remove();$(this.container + '_txt_min').remove();}
        else{$(this.container + '_count_min').text(+minutes);}
        //seconds
        $(this.container + '_count_sec').text(seconds);

        //Singular text for 'reverse' assembly
        if(this.opts['order'] == 2){
            if(days <= 1){$(this.container + '_txt_days').text(this.opts['spacer'] + ' dag en ');}
            else{$(this.container + '_txt_days').text(this.opts['spacer'] + ' dagen en ')}
            if(hours == 1){$(this.container + '_txt_hours').text(this.opts['spacer'] + ' uur en ');}
            else{$(this.container + '_txt_hours').text(this.opts['spacer'] + ' uur en ');}
            if(minutes == 1){$(this.container + '_txt_min').text(this.opts['spacer'] + ' min');}
            else{$(this.container + '_txt_min').text(this.opts['spacer'] + ' min');}
            if(seconds == 1){$(this.container + '_txt_sec').text(this.opts['spacer'] + '');}
            else{$(this.container + '_txt_sec').text(this.opts['spacer'] + '');}
        }

        //end of countdown
        if(days <= 0 && hours <= 0 && minutes <= 0 && seconds <= 0){
            //timer is over, final output
            //if date is today!
            if(new Date().toDateString() == targetDate.toDateString()){
                $(this.container).addClass('count_now');
                $(this.container).text(this.opts['dayOf']);
            }else{//if date is after today              
                $(this.container).addClass('count_end');
                $(this.container).text(this.opts['end']);
            }
            this.complete = true;
        }   
    };
    /////////////////////////////////////////////////////
    /////////////////////////////////////////////////////

    //run immediately
    this.count_update();

    //now loop this every second
    var selfobject = this; //scope gets lost within setInterval (see: http://www.vonloesch.de/node/32)
    var theCounter = setInterval(function(){
        selfobject.count_update();
            if(selfobject.complete == true){
                clearInterval(theCounter);}
        }, 1000);
}

HTML:

$(document).ready(function() {
var aanbiedingcountdown = new BK_CountDown('#deal1', '05/25/2014', '23:57', {order: 2, spacer: ''}); var aanbiedingcountdown = new BK_CountDown('#deal2', '05/26/2014', '23:57', {order: 2, spacer: ''}); var aanbiedingcountdown = new BK_CountDown('#deal3', '05/28/2014', '23:57', {order: 2, spacer: ''}); var aanbiedingcountdown = new BK_CountDown('#deal4', '05/28/2014', '15:10', {order: 2, spacer: ''}); var aanbiedingcountdown = new BK_CountDown('#deal5', '05/26/2014', '23:57', {order: 2, spacer: ''}); });

您看,对于我想要的每个倒计时,我都需要创建一个 ID。 但我想要的是,当页面加载时,倒计时不需要运行,它会使我的网站变慢。因此,只有当某人刷新页面时,他才能获得正确的日期和时间。

示例:时间现在是 16:00u,倒计时设置为 17 小时,因此,当有人仍在我的网站上(10 分钟)而不刷新页面时,倒计时仍然是 16 小时,只有他刷新页面然后倒计时是16:10h...

我在其他网站上看到过这个,他们在同一页面上有 100 多个带有倒计时的产品,并且仍然可以完美运行,因为只有当人们刷新页面时计时器才会运行,计时器才会设置为正确的日期和时间。

演示:http://jsfiddle.net/uJk73/(我删除了几秒钟,我虽然没有这个网站会更快,但没有成功)

希望有人能帮我解决这个问题。

【问题讨论】:

  • 使用一个 setInterval 循环来控制所有倒计时,并减少循环次数。
  • 我必须像你一样想办法。
  • 是的,我知道,只是相同的倒计时 ID。但问题是这样的: 7 uur en 34 min 这将显示在每个产品上,这会使我的网站变慢。
  • 看起来您只需要删除 var theCounter = setInterval 并在每个实例上运行 .count_update(); 的全局范围内添加一个 setInterval。
  • 啊,你是对的,多次更改 HTML 很慢。您可以通过在追加之前使用 .detach() 并在之后添加元素来加速该部分。但它只对每个项目执行一次该部分。

标签: javascript html date timer countdown


【解决方案1】:

Updated jsfiddle

假设您有 9 笔交易

<div id="countdowntimer">
    <div id="deal1"></div>
    <div id="deal2"></div>
    <div id="deal3"></div>
    <div id="deal4"></div>
    <div id="deal5"></div>
    <div id="deal6"></div>
    <div id="deal7"></div>
    <div id="deal8"></div>
    <div id="deal9"></div>
</div>

摆脱BK_CountDown()中的这个循环

//now loop this every second
/*var selfobject = this; //scope gets lost within setInterval (see: http://www.vonloesch.de/node/32)
var theCounter = setInterval(function(){
    selfobject.count_update();
        if(selfobject.complete == true){
            clearInterval(theCounter);}
    }, 1000);
    */

然后

$(document).ready(function() {  
    var deals = []; // create an array
    deals.push( new BK_CountDown('#deal1', '05/24/2014', '23:59', {order: 2, spacer: ''}) );  
    deals.push( new BK_CountDown('#deal2', '05/24/2014', '22:59', {order: 2, spacer: ''}) );  
    deals.push( new BK_CountDown('#deal3', '05/24/2014', '12:59', {order: 2, spacer: ''}) );  
    deals.push( new BK_CountDown('#deal4', '05/24/2014', '13:49', {order: 2, spacer: ''}) );  
    deals.push( new BK_CountDown('#deal5', '05/24/2014', '14:49', {order: 2, spacer: ''}) );  
    deals.push( new BK_CountDown('#deal6', '05/24/2014', '15:57', {order: 2, spacer: ''}) );  
    deals.push( new BK_CountDown('#deal7', '05/24/2014', '15:58', {order: 2, spacer: ''}) );  
    deals.push( new BK_CountDown('#deal8', '05/24/2014', '15:59', {order: 2, spacer: ''}) );  
    deals.push( new BK_CountDown('#deal9', '05/24/2014', '16:00', {order: 2, spacer: ''}) );  


    var dealcounter = setInterval(function(){ // create one setTimeout
        if (deals.length){
            for (i in deals){
                var selfobject = deals[i];
                selfobject.count_update();
                if(selfobject.complete == true) delete deals[i]; // remove from array 
            }
        }else{
            clearTimeout(dealcounter); // no more to count down, stop this loop
        }
    }, 5000); // 5 seconds

});

【讨论】:

  • 不,HTML 每秒都在变化。你的第一个答案就足够了。 this.count_update();(function() jsfiddle.net/uJk73/4 我不确定这是否可以,但在控制台中我没有收到警告或错误。
  • 文字每次更新。附加只发生一次。 ^ 这个答案是我的第一个答案 - 一个 setTimeout。您可以仅在文本实际上与现有文本不同时才更改文本,但我想知道 DOM 是否有该检查。
  • 我不确定这个,现在你把我弄糊涂了……上面的代码,我把它放在我的网店产品html中,但他不想要。我没有收到任何错误或警告,只是倒计时没有出现,并且不确定你所说的这种情况只发生一次。我尝试了上面的代码(第一个答案)并用许多产品(109)对其进行了测试,它可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多