javascript范围? - jquery插件倒计时器

时间:2011-07-10 09:19:11

标签: javascript jquery jquery-plugins scope

嗨,我有一个问题,其中范围似乎丢失了。我做错了什么?

假设逻辑是从每个计数器减少1秒而不是从最后一个计数器减少。 我做错了什么?

<html>
<head>
    <link rel="stylesheet" href="http://static.jquery.com/files/rocker/css/reset.css" type="text/css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript">
        (function($){
            $.fn.extend({

                countdown: function(options) {

                var defaults = {
                    daysSelector : 'span.days',
                    hoursSelector : 'span.hours',
                    minutesSelector : 'span.minutes',
                    secondsSelector : 'span.seconds'
                }

                var options =  $.extend(defaults, options);
                var _this  = $(this);

                tick =  function()
                {
                    var days = _this.find(options.daysSelector);
                    var hours = _this.find(options.hoursSelector);
                    var minutes = _this.find(options.minutesSelector);
                    var seconds = _this.find(options.secondsSelector);
                    console.log(_this);
                    var currentSeconds=seconds.text();
                    currentSeconds--;
                    if(currentSeconds<0)
                    {
                        seconds.text("59");
                        var currentMinutes=minutes.text();
                        currentMinutes--;
                        if(currentMinutes<0)
                        {
                            (minutes).text("59");
                            var currentHours=(hours).text();
                            currentHours--;
                            if(currentHours<0)
                            {
                                (hours).text("23"); 
                                var currentDays=(hours).text();
                                currentDays--;
                            }
                            else
                            {
                                if(currentHours.toString().length==1)
                                {
                                    (hours).text('0'+currentHours);
                                }
                                else
                                {
                                    (hours).text(currentHours);
                                }
                            }
                        }
                        else
                        {
                            if(currentMinutes.toString().length==1)
                            {
                                (minutes).text('0'+currentMinutes);
                            }
                            else
                            {
                                (minutes).text(currentMinutes);
                            }
                        }
                    }
                    else
                    {
                        if(currentSeconds.toString().length==1)
                        {
                            seconds.text('0'+currentSeconds);
                        }
                        else
                        {
                            seconds.text(currentSeconds);
                        }
                    }   
                }

                return this.each(function() 
                {
                    console.log(_this);
                    setInterval("this.tick()",1000);
                });
            }
        });

        })(jQuery);

        $(document).ready(function()
        {
            $("#timer1").countdown();
            $("#timer2").countdown();
            $("#timer3").countdown();
        });

    </script>


</head>

<body>

    <div id="timer1">
        <span class="days">1</span>
        <span class="hours">18</span>
        <span class="minutes">6</span>
        <span class="seconds">45</span>
    </div>

    <div id="timer2">
        <span class="days">2</span>
        <span class="hours">28</span>
        <span class="minutes">1</span>
        <span class="seconds">59</span>
    </div>

    <div id="timer3">
        <span class="days">10</span>
        <span class="hours">0</span>
        <span class="minutes">59</span>
        <span class="seconds">59</span>
    </div>


</body>

3 个答案:

答案 0 :(得分:1)

如果我必须猜测问题是什么......只有1个计时器实际倒计时,而其他两个计时器没有?

那是因为扩展倒数计时器功能你从未将倒数计时器的名称(id)传递给该功能。所以它始终只执行最后一个,因为最后一个是被称为... last。

您需要通过div的名称(id)发送,以便同时倒计时3。

答案 1 :(得分:1)

您在全局范围内声明了tick。让它在当地:

var tick =  function()...

并且不要将字符串传递给setInterval

setInterval(tick,1000);

更好的插件结构是仅声明tick函数一次并将当前元素(或时间字段)作为参数传递:

(function($){
     var tick = function(days, hours, minutes, seconds) {
         //...
     };

     $.fn.countdown = function(options) {

            var defaults = {
                daysSelector : 'span.days',
                hoursSelector : 'span.hours',
                minutesSelector : 'span.minutes',
                secondsSelector : 'span.seconds'
            }

            var options =  $.extend(defaults, options);

            return this.each(function(){
                var days = $(this).find(options.daysSelector);
                var hours = $(this).find(options.hoursSelector);
                var minutes = $(this).find(options.minutesSelector);
                var seconds = $(this).find(options.secondsSelector);
                setInterval(function() {
                    tick(days, hours, minutes, seconds);
                },1000);
            });
       };
}(jQuery));

如果您一次选择多个元素,那么您的插件也可以使用:

$("#timer1, #timer2, #timer3").countdown();
否则 无效(请参阅此处http://jsfiddle.net/fkling/kvqWR/5/)。

工作DEMO

最好只让setInterval继续对所选元素进行迭代并执行操作。你拥有的计时器越少越好。看一下这个例子:http://jsfiddle.net/fkling/kvqWR/4/

答案 2 :(得分:1)

我编辑了你的代码

(function($){
            $.fn.extend({

                countdown: function(options) {

                var defaults = {
                    daysSelector : 'span.days',
                    hoursSelector : 'span.hours',
                    minutesSelector : 'span.minutes',
                    secondsSelector : 'span.seconds'
                }

                var options =  $.extend(defaults, options);
                var _this  = $(this);

               var tick =  function()
                {
                    var    days = _this.find(options.daysSelector);
                    var    hours = _this.find(options.hoursSelector);
                    var    minutes = _this.find(options.minutesSelector);
                    var    seconds = _this.find(options.secondsSelector);
                    console.log(_this);
                    var currentSeconds=seconds.text();
                    currentSeconds--;
                    if(currentSeconds<0)
                    {
                        seconds.text("59");
                        var currentMinutes=minutes.text();
                        currentMinutes--;
                        if(currentMinutes<0)
                        {
                            (minutes).text("59");
                            var currentHours=(hours).text();
                            currentHours--;
                            if(currentHours<0)
                            {
                                (hours).text("23");    
                                var currentDays=(hours).text();
                                currentDays--;
                            }
                            else
                            {
                                if(currentHours.toString().length==1)
                                {
                                    (hours).text('0'+currentHours);
                                }
                                else
                                {
                                    (hours).text(currentHours);
                                }
                            }
                        }
                        else
                        {
                            if(currentMinutes.toString().length==1)
                            {
                                (minutes).text('0'+currentMinutes);
                            }
                            else
                            {
                                (minutes).text(currentMinutes);
                            }
                        }
                    }
                    else
                    {
                        if(currentSeconds.toString().length==1)
                        {
                            seconds.text('0'+currentSeconds);
                        }
                        else
                        {
                            seconds.text(currentSeconds);
                        }
                    }    
                }

                return _this.each(function() 
                {
                    console.log(_this);
                    setInterval(tick,1000);
                });
            }
        });

        })(jQuery);

        $(document).ready(function()
        {
            $("#timer1").countdown();
            $("#timer2").countdown();
            $("#timer3").countdown();
        });

tick是全局的,这就是问题(也永远不会将代码传递给setInterval!

在这里小提琴:http://jsfiddle.net/kvqWR/1/