倒计时栏 Javascript 没有减少

Countdown bar Javascript not decreasing

我有一个倒计时进度条的 JS 代码,它应该取一个时间值并减少直到到达时间,然后显示 EXPIRED。

function progress(timeleft, timetotal, $element) {
  var bar = document.getElementById("#progressBar")
  var progressBarWidth = (timeleft * bar.width()) / timetotal
  console.log("width is" + bar.width() + "time left is" + timeleft)
  $element.find("div").animate({
    width: progressBarWidth
  }, timeleft == timetotal ? 0 : 1000, "linear")

  if (timeleft > 0) {
    setTimeout(function() {
      progress(timeleft - 1, timetotal, $element)
    }, 1000)
  }
}

progress(180, 180, $("#progressBar"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="progressBar">
  <div></div>
</div>

问题是我这里设置为3分钟进行测试,bar没有减少。我已经通过控制台进行了调试,'bar.width()' 似乎未定义。任何想法如何解决它?谢谢!

这不应该

var bar = document.getElementById("#progressBar")

就是这个

var bar = document.getElementById("progressBar")

https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById

bar.width()

成为

bar.clientWidth

https://developer.mozilla.org/en-US/docs/Web/API/Element

您已经传递了 $elementIS bar

function progress(timeleft, timetotal, $element) {
  var progressBarWidth = (timeleft * $element.width()) / timetotal
  console.log(`width: ${$element.width()} px  |  time left: ${timeleft} sec`)
  $element.find("div").animate({
    width: progressBarWidth
  }, timeleft == timetotal ? 0 : 1000, "linear")

  if (timeleft > 0) {
    setTimeout(progress, 1000, timeleft - 1, timetotal, $element)
  }
}

progress(60, 60, $("#progressBar"))
#progressBar div {
  background: green;
  height: 1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="progressBar">
  <div></div>
</div>

注意: 您可以调用 setTimeout 而无需创建嵌套函数调用。超时后的参数(第二个参数)将被传递到回调函数中。

替换为:

if (timeleft > 0) {
  setTimeout(function() {
    progress(timeleft - 1, timetotal, $element)
  }, 1000)
}

有了这个:

if (timeleft > 0) {
  setTimeout(progress, 1000, timeleft - 1, timetotal, $element)
}

jQuery插件!

这是一个jQuery插件版本

(($) => {
  const init = ($bar) => {
    if ($bar.find('div').length === 0) $bar.append($('<div>'));
  }
  const run = ($bar, duration, timeRemaining, callback) => {
    update($bar, duration, timeRemaining)
    if (timeRemaining > 0) {
      setTimeout(tick, 1000, $bar, duration, timeRemaining, callback)
    } else {
      callback()
    }
  }
  const update = ($bar, duration, timeRemaining) => {
    const width = (timeRemaining * $bar.width()) / duration
    $bar.find('div').animate({
      width: width
    }, timeRemaining == duration ? 0 : 1000, 'linear')
  }
  const tick = ($bar, duration, timeRemaining, callback) => {
    run($bar, duration, timeRemaining - 1, callback)
  }
  $.fn.progress = function(duration, timeRemaining, callback) {
    init(this)
    run(this, duration, timeRemaining, callback);
    return this
  }
})(jQuery);

$('#progress-bar-1').progress(10, 10, () => {
  console.log('Task #1 completed!')
})

$('#progress-bar-2').progress(5, 5, () => {
  console.log('Task #2 completed!')
})
div[id^="progress-bar"] div {
  background: green;
  height: 1em;
  margin-bottom: 0.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="progress-bar-1"></div>
<div id="progress-bar-2"></div>