2022-09-26 工作记录--React-js将时间戳转换成“时分秒”+“时分秒”的倒计时(含tab切换)

一、实现效果

请添加图片描述

假如后端返了两个数据:当前时间13位时间戳currentTimestamp秒抢时间13位时间戳seckillTimestamp,想实现“距开始秒抢”的倒计时,即:秒抢时间与当前时间之间的时间差以“时分秒”的形式进行倒计时,如下动图:

请添加图片描述

二、实现方式

第一步、封装方法——js将时间戳转换成“时分秒”

【注意】:是“时分秒”,不是 “天时分秒”哦~ (二者写法是有区别滴哦)
请添加图片描述

utils.js

/** 
 1、js获取 倒计时 时分秒
 通过时间戳的方式来 
 let h =  Math.trunc(dec / 3600); // 时
 let m =  Math.trunc(dec % 3600 / 60); // 分
 let s =  Math.trunc(dec % 3600 % 60); // 秒
 2、参数分析:
 @param {Num} inputTime: 需要转换成 时分秒 的 13位时间戳
 @param {Boolean} isPop: 便于实现两种返回结果:true -> `${h}小时${m}分${s}秒` ; false -> 包含时分秒的finalDateObj对象
 */
function timestampFormatter(inputTime, isPop = false) {
  // 最终时间结果对象
  const finalDateObj = {
    h: null, // 小时
    m: null, // 分钟
    s: null, // 秒
  }
  
  // 剩余时间总的毫秒数 除以 1000 变为总秒数(时间戳为13位 需要除以1000,为10位 则不需要)
  let dec = inputTime / 1000;
  
  if (dec <= 0) {
    dec = 0;
  }
  
  // 得到小时 格式化成前缀加零的样式
  let h = Math.trunc(dec / 3600);
  h = h < 10 ? '0' + h : h;
  // 得到分钟 格式化成前缀加零的样式
  let m = Math.trunc(dec % 3600 / 60);
  m = m < 10 ? '0' + m : m;
  // 得到秒 格式化成前缀加零的样式
  let s = Math.trunc(dec % 3600 % 60);
  s = s < 10 ? '0' + s : s;

  finalDateObj.h = h;
  finalDateObj.m = m;
  finalDateObj.s = s;

  return isPop ? `${h}小时${m}${s}` : finalDateObj;
}

第二步、实现“时分秒”的倒计时

请添加图片描述

实现思路同我的另外一篇博文,相比其代码,只是有两处区别,如下:

countDownComponent.jsx

这是含倒计时的子组件。

1、倒计时初始值

参考项目代码:

// 1、初始化state
state = { 
  	canCountDown: true, // 判断是否开启定时器
  	finalDate: '00天00小时00分', // 倒计时初始值
}

现项目代码:

// 1、初始化state
state = { 
  canCountDown: true, // 判断是否开启定时器
  h1: '0', // 倒计时初始值-时
  h2: '0', // 倒计时初始值-时
  m1: '0', // 倒计时初始值-分
  m2: '0', // 倒计时初始值-分
  s1: '0', // 倒计时初始值-秒
  s2: '0', // 倒计时初始值-秒 
}

2、获取到倒计时最终值【位于方法updateTime里】

参考项目代码:

/** 调用上面封装的方法timestampFormatter,计算到倒计时的展示结果,并state赋值,方便html里进行展示 */
const result = timestampFormatter(countDownTimestamp, true);
this.setState({
  	finalDate: result,
})

现项目代码:

/** 调用上面封装的方法timestampFormatter,计算到倒计时的展示结果,并state赋值,方便html里进行展示 */
const _h = timestampFormatter(countDownTime).h + '';
const _m = timestampFormatter(countDownTime).m + '';
const _s = timestampFormatter(countDownTime).s + '';
this.setState({
     h1: _h.slice(0, 1),
     h2: _h.slice(-1),
     m1: _m.slice(0, 1),
     m2: _m.slice(-1),
     s1: _s.slice(0, 1),
     s2: _s.slice(-1),
})

第三步、HTML渲染

render(){
	const { h1, h2, m1, m2, s1, s2 } = this.state;
	return(
		<div __examplenotes="倒计时" className="countDown">
             <span __examplenotes="倒计时背景" className="countDownBg"></span>
             <span __examplenotes="时" className="commonTime hour1">{h1}</span>
             <span __examplenotes="时" className="commonTime hour2">{h2}</span>
             <span __examplenotes="分" className="commonTime minute1">{m1}</span>
             <span __examplenotes="分" className="commonTime minute2">{m2}</span>
             <span __examplenotes="秒" className="commonTime second1">{s1}</span>
             <span __examplenotes="秒" className="commonTime second2">{s2}</span>
       </div>
	 )
}

三、坑?

如上结果动图可知:我们实现的是一个可以tab切换的倒计时项目。

  • 实现思路:把倒计时相关的部分封装成一个组件,随之渲染页面。
  • 坑?:当tab1里的第一条数据的倒计时小于0时,tab2里的第一条数据的倒计时 自动归置为0(即使 其并非为0);当tab1里的第二条数据的倒计时小于0时,tab2里的第二条数据的倒计时 自动归置为0(即使 其并非为0);依次类推。。。
  • 分析原因:原来是因为我们在更新倒计时时间时定义了如下代码【当倒计时小于0时,定时器被关闭了】,如下图所示:
    在这里插入图片描述
  • 解决方法:我们需要在切换tab时,判断组件的定时器timer是不是null,如果是nullcountDownTimestamp大于0,调下funTimer(),重新开启定时器,代码如下:【需结合我的另外一篇博文一起看哦~】

countDownComponent.jsx

这是含倒计时的子组件。

componentDidMount() {
	// 发送事件"startTimer"
    document.addEventListener("startTimer", this.startTimer, this);
}

componentWillUnmount() {
	// 移除事件"startTimer"
    document.removeEventListener("startTimer", this.startTimer, this);
}

// 判断组件的定时器timer是不是null,如果是null且countDown大于0,调下funTimer()
startTimer = () => {
   	/** seckillTimestamp:秒杀开始时间的时间戳,currentTimestamp:当前时间的时间戳 */
    const seckillTimestamp = 1664280000000; // 秒杀开始时间【实际情况时 由后台返回,这儿写死只是做个测试】
    /** 计算倒计时的展示结果,并return值,方便html里进行展示 */
    const countDownTimestamp = seckillTimestamp * 1 - this.currentTimestamp * 1; // 计算得到 倒计时 的时间戳
    if (this.timer == null && countDownTimestamp > 0) {
        this.FunTimer();
    }
}

homePage.jsx

这是调用倒计时子组件的首页

// 标题tab切换按钮 - 0->今日秒抢, 1->明日秒抢
switchTitle = _throttle(async (index) => {
   // 调用组件CountDownComponent里的方法
   document.dispatchEvent(new CustomEvent("startTimer", {}));
}, 1000)

请添加图片描述


版权声明:本文为weixin_48850734原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。