事情是这样的,昨天有个粉丝问我:如何每隔2分钟弹出一次弹出框。
我说 那不就是setInterval嘛,然后设定2分钟执行一次。
他说 不是的,这个2分钟只是我说的一个时间,不是常量,是服务端下发的。
我说 那就获取了这个时间值再定时。
他说 但是如果用户把浏览器关了,如果2分钟内又打开了,得记住时间,然后距离上次如果到2分钟了,就弹出,如果超过了就直接弹,不用等了。
我说 看来还得记录一下每次的时间啊。但如果每次记住了,存到localStorage里,用户如果不刷新,还拿不到最新值。
他说 是啊,很费劲。
1 需求分析
- 首次来到页面,直接弹出;
- 首次弹出后,记录时间点,记录距离下次的时间点;
- 这个时间点得存到localStorage里;
- 但是存到localStorage里呢,用户如果不刷新页面,下次的时间点就拿不到;
- 所以需要本地再存一份,可以存到一个变量里;
- 首次弹出后,开始倒计时,倒计时的时间值为终点值 减去 当前时间
- 如果用户关闭浏览器,再打开,需要获取localStorage时间,再与当前时间对比,超出则直接弹出,开始计算下一次的时间点,未超出,则继续倒计时,倒计时的值为终点值 减去 当前时间
2 代码实现
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title></title><style></style></head><body><script>var myTime = 0;var timeExp = 1000*60*2; // 设定2分钟后继续打印// 第一次执行function first() {// 第一次就要弹框console.log('第一次弹框');// 第一次弹框把时间记录下来,记录的是下次打印的时间点var newDate = new Date().getTime() + timeExp;myTime = newDate;localStorage.setItem('t', newDate);}function timerFn() {// 对比localStorage,如果是第一次localStorage没有值,myTime为flase,first执行// 如果localStorage有值,myTime也有值了,first就不执行了myTime = localStorage.getItem('t');// 无记录,第一次开始执行if (!myTime) {first();}// 执行完成一次后,不管刷新或者不刷新,myTime都有值了var newDate1 = new Date().getTime();if (newDate1 >= myTime) {console.log('打印');// 然后开始记录下次打印时间myTime = newDate1 + timeExp;localStorage.setItem('t', newDate1 + timeExp);// 开始安装下次定时器timerFn();} else { // 如果时间没过,稍后才到时间// 看看还差多久才打印var laterTime = myTime - newDate1;setTimeout(() => {console.log('打印');// 然后开始记录下次打印时间var newDate2 = new Date().getTime();myTime = newDate2 + timeExp;localStorage.setItem('t', newDate2 + timeExp);// 开始安装下次定时器timerFn();}, laterTime)}}timerFn();</script></body>
</html>