【问题标题】:javascript scoping? - jquery plugin countdown timerjavascript范围? - jquery 插件倒数计时器
【发布时间】:2011-07-10 09:19:10
【问题描述】:

您好,我遇到了范围界定似乎丢失的问题。我做错了什么?

假设逻辑是从每个计数器减少 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>

【问题讨论】:

  • 你能把代码贴在这里吗?Stackoverflow 不依赖外部服务来回答他的问题。
  • 在这里贴出相关部分的代码
  • 请查看我的回答,了解一些改进插件的建议。

标签: javascript jquery jquery-plugins scope


【解决方案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/

【讨论】:

    【解决方案2】:

    如果我必须猜测问题出在哪里...实际上只有 1 个计时器倒计时,而其他两个没有?

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

    您需要通过 div 的名称 (id) 发送它以同时倒计时所有 3 个。

    【讨论】:

      【解决方案3】:

      您在全局范围内声明了 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/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-20
        • 1970-01-01
        • 1970-01-01
        • 2011-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多