Javascript div 宽度倒计时

Javascript div width countdown

我正在尝试通过 div 的宽度可视化倒计时。这可以用于显示下一个横幅何时滑入的横幅系统,或用于显示通知可见多长时间的通知系统。

所以在我下面的示例中,我在 5 秒后清空了 .outer div,但是 .timer div 的宽度没有达到 width: 0%;setTimeout() 启动的同时。

变量 len 表示横幅或通知的显示时长。

变量 offset 中的计算让我失望(我认为),我似乎无法正确计算。我希望它是动态的,也就是说,无论 len 是什么以及 outer/parent div 的宽度是多少,它总是需要 len 时间才能到达 width: 0%;.

希望我的解释有道理。任何帮助将不胜感激。

const len = 5000;
let outer = document.querySelector('.outer');

let timer = document.querySelector('.timer');
let timerWidth = timer.offsetWidth;
let offset = len / timerWidth;
let init = 100;

let interval = setInterval(() => {
   init = init - offset;
   timer.style.width = init + '%';
}, 1000);

setTimeout(() => {
   outer.innerHTML = '';
   clearInterval(interval);
}, len);
* {
  box-sizing:border-box;
}

body {
  padding: 100px 10px 10px;
}

.outer {
  width: 100%;
  border: 1px solid slategray;
  padding: 10px;
}

.timer {
  width: 100%;
  height: 10px;
  background: red;
  transition: all 1000ms linear;
}
<div class="outer">
  <div class="timer"></div>
  <p>Some Message Here!</p>
</div>

如果您使用宽度百分比,则无需知道框的宽度。 你只需要减去并添加超时偏移量。

const len = 5000;
let outer = document.querySelector('.outer');

let timer = document.querySelector('.timer');
let timerWidth = timer.offsetWidth;
let offset = 100 * 1000 / 5000;


let interval = setInterval(() => {
init = init - 20;
timer.style.width = init + '%';
}, 1000);

setTimeout(() => {
outer.innerHTML = '';
clearInterval(interval);
}, len + 1000);

代码的两个问题:

  1. interval 不会在页面加载后立即启动,因此 CSS 过渡较晚。
  2. offset确实错了

这是我修复它的方法:

let toElapse = 3000; // modify as you like
let tick = 1000; //if you modify this don't forget to replicate 
                 //in CSS transition prop
let countDownEl = document.querySelector('#countdown');
let outer = document.querySelector('.outer');
let timer = document.querySelector('.timer');
let init = 100;
// we calculate the offset based on the tick and time to elapse
let offset = init / (toElapse/tick); 
countDownEl.innerHTML = init;

setTimeout(()=>{
  // we need to start the first CSS transition ASAP so it is not late.
  init = init - offset;
  timer.style.width = init.toFixed(2) + '%';
},0)

let interval = setInterval(() => {
  // the same interval.
  countDownEl.innerHTML = init;
  init = init - offset;
  timer.style.width = init.toFixed(2) + '%';
}, tick);

setTimeout(() => {
   // the same clearance timeout
   outer.innerHTML = '';
   clearInterval(interval);
}, toElapse);
* {
  box-sizing:border-box;
}

body {
  padding: 100px 10px 10px;
}

.outer {
  width: 100%;
  border: 1px solid slategray;
  padding: 10px;
}

.timer {
  width: 100%;
  height: 10px;
  background: red;
  transition: width 1s linear;
}
<div class="outer">
  
  <div class="timer"></div><span id="countdown"></span>
  <p>Some Message Here!</p>
</div>