在setInterval

时间:2015-11-24 09:40:41

标签: jquery timer

我发现了这个Pie Timer并对其进行了一些修改,因此它适合我的项目(更改颜色和大小)。我需要它每12秒执行一次,所以我把它放在setInterval函数中。现在看来如下: JSFIDDLE 但有两个问题:

  1. 第一次执行时,等待12秒钟开始。如何摆脱这种最初的延迟?
  2. 只有第一个周期完全。所有下一次运行都是从中途开始,而不是从开始。
  3. 虽然我可以忍受最初的延迟,但这种中间的事情正在扼杀我。有什么办法可以解决吗?

    function pieTimer(){    
        var totaltime = 120;
        function update(percent){
            var deg;
            if (percent<(totaltime/2)){
                deg = 90 + (360*percent/totaltime);
                $('.pie').css('background-image',
                'linear-gradient('+deg+'deg, transparent 50%, white 50%),linear-gradient(90deg, white 50%, transparent 50%)'
                );
            } 
            else if (percent>=(totaltime/2)){
                deg = -90 + (360*percent/totaltime);
                $('.pie').css('background-image',
                'linear-gradient('+deg+'deg, transparent 50%, #e31630 50%),linear-gradient(90deg, white 50%, transparent 50%)'
                );
            }   
        }
        var count = parseInt($('#time').text());
        myCounter = setInterval(function () {
            count+=1;
            $('#time').html(count);
            update(count);
    
            if(count==totaltime)
                 clearInterval(myCounter);
        }, 100);
    }
    setInterval(pieTimer, 12000);
    

2 个答案:

答案 0 :(得分:0)

第一点只是在正文结束前调用函数或使用jQuery文档就绪语句。

<body>
<div class="pie degree">
        <span class="block"></span>
        <span id="time">0</span>
    </div>
    <script>pieTimer();</script>
</body>

对于第二点,当它等于总时间时,你必须重置计数变量

function pieTimer(){    
    var totaltime = 120;
    function update(percent){
        var deg;
        if (percent<(totaltime/2)){
            deg = 90 + (360*percent/totaltime);
            $('.pie').css('background-image',
            'linear-gradient('+deg+'deg, transparent 50%, white 50%),linear-gradient(90deg, white 50%, transparent 50%)'
            );
        } 
        else if (percent>=(totaltime/2)){
            deg = -90 + (360*percent/totaltime);
            $('.pie').css('background-image',
            'linear-gradient('+deg+'deg, transparent 50%, #e31630 50%),linear-gradient(90deg, white 50%, transparent 50%)'
            );
        }   
    }
    var count = parseInt($('#time').text());
    myCounter = setInterval(function () {
        count+=1;
        $('#time').html(count);
        update(count);

        if(count==totaltime){
            clearInterval(myCounter);
            count = 0;
        }

    }, 100);
}

答案 1 :(得分:0)

您可能希望考虑更新的方法,主要基于问题中的代码,但封装在构造函数中,允许:

  • 要传入的参数,以控制计时器的行为。
  • .start()和.stop()方法从外部调用。
  • 如果需要,
  • 同一页面上的多个独立计时器。

更改内部逻辑允许:

  • 更好的时间 - 基于超时,而不是(丑陋)计数器在setInterval中递增。
  • 更新间隔,与总时间无关。

通过从.start()方法返回Promise,可以在外部上执行控制:

  • 计时器到期时会发生什么。
  • 如果计时器过早停止会发生什么。

这是构造函数......

function PieTimer(containerSelector, interval, totaltime) {
    var $container = $(containerSelector),
        myCounter,
        dfrd;

    // input range checks
    if($container.length === 0) return;
    interval = Math.max(+interval || 0, 50);
    totaltime = Math.max(+totaltime || 0, 1000);

    function update(t0) {
        var p = (Date.now() - t0) / totaltime, // proportion, from 0.0 to 1.0
            deg; 
        if (p < 0.5) {
            deg = 90 + 360 * p;
            $container.css('background-image', 'linear-gradient('+deg+'deg, transparent 50%, white 50%), linear-gradient(90deg, white 50%, transparent 50%)');
        } else if (p >= 0.5) {
            deg = -90 + 360 * p;
            $container.css('background-image', 'linear-gradient('+deg+'deg, transparent 50%, #e31630 50%), linear-gradient(90deg, white 50%, transparent 50%)');
        }
    }
    //Public start method
    this.start = function() {
        this.stop("timer was restarted before expiry"); // in case .start() is called while timer is still running.
        myCounter = setInterval(update.bind(null, new Date()), interval); //animate the timer
        dfrd = $.Deferred(function(dfrd) { // create a Deferred object
            setTimeout(dfrd.resolve, totaltime); // resolve the Deferred after the totaltime period
        });
        return dfrd.then(this.stop); // stop the timer when the Deferred resolves, and return a promise based on the Deferred. Note, `dfrd.reject()` will have no effect as `dfrd.resolve()` has already been called.
    };
    //Public stop method
    this.stop = function(msg) {
        msg = msg || 'timer was stopped before expiry';
        clearInterval(myCounter); // stop the animation
        if(dfrd) {
            dfrd.reject(new Error(msg)); // provide a reason why the timer was stopped, and allow some external action to be taken.
        }
    };
}

以下是如何使用它......

var pieTimer = new PieTimer(".pie", 100, 12000);
(function runTimer() {
    pieTimer.start().then(runTimer);
})();

<强> Demo

正如您将在演示中看到的那样,“start”将始终从零重启计时器。它的行为不像秒表,其中“开始”按钮将从上一次“停止”时定时器停止的位置重新启动,并且需要单独的“重置”按钮(或“启动”按钮上的循环动作) 。那将是更多的工作。