Javascript/jQuery 倒计时器未正确初始化

标签 javascript jquery function

我有一个倒计时器,我对原来的计时器进行了修改,但它似乎不起作用。我强调的问题是 startCountdown(startDate,deadlineDate,expiredText) 没有触发它返回 undefined。代码中的其他所有内容都按预期触发并返回正确的结果,有什么想法吗?

我已添加以下所有信息,其中包含控制台日志等。

jQuery(document).ready(function($) {
  $('.clockdiv').each(function() {
    //START Get required values
    var startDate = $(this).find(".start").attr("rel"); //Gets start date of offer
    var deadlineDate = $(this).find(".end").attr("rel"); //Gets deadline date of offer
    var expiredText = $(this).find(".expired").attr("rel"); //Gets expired coupon text
    //END Get required values

    function getTimeRemaining(deadlineDate, startDate) {
      var pD = Date.parse(deadlineDate); //Get the amount of milliseconds until the end date
      var pS = Date.parse(startDate); //Get the amount of milliseconds since the start date
      var t = pD - pS; //Find out how many milliseconds from start date to the deadline date
      var s = Math.floor((t / 1000) % 60); //Works out how many seconds until the deadline
      var m = Math.floor((t / 1000 / 60) % 60); //Works out how many minutes until the deadline
      var h = Math.floor((t / (1000 * 60 * 60)) % 24); //Works out how many hours until the deadline
      var d = Math.floor(t / (1000 * 60 * 60 * 24)); //Works out how many days until the deadline

      return { //Return the value of the total time remaining
        'total': t, //Return the value of the total time remaining
        'days': d, //Return the value of the days remaining
        'hours': h, //Return the value of the hours remaining
        'minutes': m, //Return the value of the minutes remaining
        'seconds': s //Return the value of the seconds remaining
      };
    }

    function startCountdown(startDate, deadlineDate, expiredText) {
      var dC = $(this).find('div > .days'); //Get the days container of the clock
      var hC = $(this).find('div > .hours'); //Get the hours container of the clock
      var mC = $(this).find('div > .minutes'); //Get the minutes container of the clock
      var sC = $(this).find('div > .seconds'); //Get the seconds container of the clock

      function updateClock(startDate, deadlineDate, expiredText) {
        var t = getTimeRemaining(deadlineDate, startDate); //Reassign the value of t to be the output of getTimeRemaining fuction

        dC.innerHTML = t.days; //Set the innerHTML to display the days remaining
        hC.innerHTML = ('0' + t.hours).slice(-2); //Set the innerHTML to display the hours remaining
        mC.innerHTML = ('0' + t.minutes).slice(-2); //Set the innerHTML to display the minutes remaining
        sC.innerHTML = ('0' + t.seconds).slice(-2); //Set the innerHTML to display the seconds remaining

        if (t.total <= 0) { //If there is no time remaining then do the following
          clearInterval(clockLoop); //Stop the 1s looping of the clockLoop
          $(this).innerHTML = '<p>' + expiredText + '</p>'; //Display the expiredText value inside of the clockdiv
        }

        console.log(startDate); // 2019/07/25 13:00:00
        console.log(deadlineDate); // 2019/07/26 14:00:00
        console.log(expiredText); // Offer Expired
        console.log(t); // {total: 90000000, days: 1, hours: 1, minutes: 0, seconds: 0}
        console.log(dC); // a.fn.init [selector: "div > .days", prevObject: a.fn.init(1), context: document, innerHTML: 1]
        console.log(hC); // a.fn.init [selector: "div > .hours", prevObject: a.fn.init(1), context: document, innerHTML: "01"]
        console.log(mC); // a.fn.init [selector: "div > .minutes", prevObject: a.fn.init(1), context: document, innerHTML: "00"]
        console.log(sC); // a.fn.init [selector: "div > .seconds", prevObject: a.fn.init(1), context: document, innerHTML: "00"]
        console.log(t.total); // 90000000
        console.log(t.days); //1
        console.log(t.hours); //1
        console.log(t.minutes); //0
        console.log(t.seconds); //0
      }
      updateClock(startDate, deadlineDate, expiredText); //Run the updateClock function
      console.log(updateClock(startDate, deadlineDate, expiredText)); //1
      var clockLoop = setInterval(updateClock, 1000); //Define the clockLoop to run the updateClock function every second
      console.log(clockLoop); // undefined
    }

    startCountdown(startDate, deadlineDate, expiredText); //Initiate the startCountdown clock
    console.log(startCountdown(startDate, deadlineDate, expiredText)); // undefined
  });
});
#clockdiv {
    color: #74b848;
    display: block;
    font-weight: 100;
    text-align: center;
    font-size: 35px;
    font-weight: bold;
    margin: 0 auto 10px;
    max-width: 320px; }

#clockdiv > div {
    flex: 20%;
    padding: 5px;
    border-radius: 3px;
    background: #74b848;
    display: inline-block;
}

#clockdiv div > span {
    padding: 10px;
    width: 100%;
    border-radius: 3px;
    background: #FFFFFF;
    display: inline-block;
}

#clockdiv .smalltext {
    padding-top: 5px;
    font-size: 16px;
    font-weight: normal;
    color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="clockdiv" class="clockdiv">
  <span class="start" rel="2019/07/25 13:00:00"></span><br>
  <span class="end" rel="2019/07/26 14:00:00"></span><br>
  <span class="expired" rel="Offer Expired"></span>
  <p></p>
  <div><span id="days" class="days"></span>
    <p></p>
    <div class="smalltext">Days</div>
  </div>
  <div><span id="hours" class="hours"></span>
    <p></p>
    <div class="smalltext">Hours</div>
  </div>
  <div><span id="minutes" class="minutes"></span>
    <p></p>
    <div class="smalltext">Minutes</div>
  </div>
  <div><span id="seconds" class="seconds"></span>
    <p></p>
    <div class="smalltext">Seconds</div>
  </div>
</div>

更新:在每个函数中添加了一个警报,以查看它们是否触发,并且它们都通过 getTimeRemaining 每秒循环触发,与 updateClock 的预期相同。 startCountdown 触发的次数是预期的两倍,因为页面上有 2 个时钟周期。

**更新:将 sC.innerHTML.innerhHTML 更改为 document.getElementById("seconds").innerHTML 显示数字 1 秒,但是当它运行时再次运行它返回 NaN。

最佳答案

这是它的工作版本:https://jsfiddle.net/5tfd4Lsn/1/

jQuery(document).ready(function( $ ) {
    $('.clockdiv').each(function() {
        var self = $(this);
        //START Get required values
        var startDate = self.find(".start").attr("rel"); //Gets start date of offer
        var deadlineDate = self.find(".end").attr("rel"); //Gets deadline date of offer
        var expiredText = self.find(".expired").attr("rel"); //Gets expired coupon text
        //END Get required values

        function getTimeRemaining(deadlineDate,startDate) {
            var pD = Date.parse(deadlineDate); //Get the amount of milliseconds until the end date
            //var pS = Date.parse(startDate); //Get the amount of milliseconds since the start date
            var pS = Date.now();
            var t = pD - pS; //Find out how many milliseconds from start date to the deadline date
            var s = Math.floor((t / 1000) % 60); //Works out how many seconds until the deadline
            var m = Math.floor((t / 1000 / 60) % 60); //Works out how many minutes until the deadline
            var h = Math.floor((t / (1000 * 60 * 60)) % 24); //Works out how many hours until the deadline
            var d = Math.floor(t / (1000 * 60 * 60 * 24)); //Works out how many days until the deadline

            return { //Return the value of the total time remaining
                'total': t, //Return the value of the total time remaining
                'days': d, //Return the value of the days remaining
                'hours': h, //Return the value of the hours remaining
                'minutes': m, //Return the value of the minutes remaining
                'seconds': s //Return the value of the seconds remaining
            };
        }

        function startCountdown(startDate,deadlineDate,expiredText) {
            var dC = self.find('div > .days'); //Get the days container of the clock
            var hC = self.find('div > .hours'); //Get the hours container of the clock
            var mC = self.find('div > .minutes'); //Get the minutes container of the clock
            var sC = self.find('div > .seconds'); //Get the seconds container of the clock

            function updateClock() {
                var t = getTimeRemaining(deadlineDate,startDate); //Reassign the value of t to be the output of getTimeRemaining fuction
                console.log(t);

                dC.empty().append($.parseHTML('' + t.days)); //Set the innerHTML to display the days remaining
                hC.empty().append($.parseHTML(('0' + t.hours).slice(-2))); //Set the innerHTML to display the hours remaining
                mC.empty().append($.parseHTML(('0' + t.minutes).slice(-2))); //Set the innerHTML to display the minutes remaining
                sC.empty().append($.parseHTML(('0' + t.seconds).slice(-2))); //Set the innerHTML to display the seconds remaining

                if (t.total <= 0) { //If there is no time remaining then do the following
                    clearInterval(clockLoop); //Stop the 1s looping of the clockLoop
                    self.empty().append($.parseHTML('<p>' + expiredText + '</p>')); //Display the expiredText value inside of the clockdiv
                }

            }
            updateClock(); //Run the updateClock function
            var clockLoop = setInterval(updateClock, 1000); //Define the clockLoop to run the updateClock function every seond
        }

        startCountdown(startDate,deadlineDate,expiredText); //Initiate the startCountdown clock
     });
});
  • 主要问题是您的 updateClock 函数需要参数,但在发出计时器回调时它不会接收任何参数。您应该只使用闭包中的局部变量。
  • 按照您的设置方式,它始终根据静态开始日期计算剩余时间。使用系统时间 (var pS = Date.now()) 更有意义,因此您实际上会看到它的变化。
  • 您不能依赖在计时器回调中仍然引用您的 .clockdiv 的“this”参数。我通过将其保存在名为“self”的局部变量中来修复此问题。
  • 我认为您不能简单地将内容分配给 jQuery 对象的innerHTML 属性并让它执行您期望的操作。我通常使用 $(whatever).empty().append($.parseHTML(...))。它使用 jQuery 方法清除任何现有的 DOM 元素,然后将解析后的 H​​TML 中的 DOM 附加到指定的元素。可能还有其他方法可以做到这一点。

关于Javascript/jQuery 倒计时器未正确初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57202996/

相关文章:

function - 计算连续输赢的大小

javascript - 如何在 Javascript 字符串中使用括号

javascript - 如何使用 Javascript 将格式化文本添加到剪贴板

jquery - 将悬停交互更改为点击触摸设备

php - 如何在 Joomla 模板中包含 PHP 函数文件

函数中的 C++ const 关键字

javascript - jQuery .click() 仅在加载时触发

javascript - jquery动态按钮点击不工作

javascript - jQuery 将隐藏表单字段发布到 ColdFusion 查询

javascript - 无法在 jQuery 中制作用于浏览消息的 SO float 效果