需求:将期望时间和现在的时间差显示在页面上,并让这个时间递减,形成倒计时的样子

实际运用场景:这个倒计时时间可能是距离秒杀结束时间or距离生日倒计时时间

图示:

 

思路:

定义两个时间对象,一个返回当前时间,另一个设置目标时间,两个时间对象相减,差值是时间戳(间隔毫秒数),将时间戳换算成秒数(就是代码:var sub = Math.ceil((target-current)/1000)),然后将差值秒数换算成天+时+分+秒的格式,用对象接收(一般返回数据都用对象接收,会很清晰),然后注册一个间隔定时器,让它帮我们自动刷新当前时间,然后返回差值对象

完整代码:

<body>
    <div id="box">

    </div>
    <script>
        //定义目标时间对象
        var targetDate = new Date("2022/11/11")
        function diffTime(current,target){
            var sub = Math.ceil((target-current)/1000)//时间戳
            //计算天数
            var day = parseInt(sub/(60*60*24))
            //计算小时
            var hours = parseInt(sub%(60*60*24)/(60*60))
            //计算分钟
            var minutes = parseInt(sub%(60*60)/60)
            //计算秒
            var seconds = sub%60
            var obj = {
                day:day,
                hours:hours,
                minutes:minutes,
                seconds:seconds
            }
            return obj
        }

        //用间隔定时器帮助自动输出,不用手动刷新
        setInterval(function(){
            //定义返回当前时间对象
            var currentDate = new Date()
            var res = diffTime(currentDate,targetDate)
            // console.log(res)//结果返回对象
            // document.write(`京东双11-${res.day}天${res.hours}时${res.minutes}分${res.seconds}秒`)
            // console.log(box)
            box.innerHTML = `京东双11-${res.day}天${res.hours}时${res.minutes}分${res.seconds}秒`
        },1000) 
    </script>
</body>

结果:

代码解释:

首先是定义两个时间对象,不传参数时返回当前时间,传参数是返回目标时间:

有人就会想计算它们的差值,直接就让他们相减就行了,然后再进行下面的转换为天数什么的,这里我想说的是我们可以把这些代码封装在函数里面,当你后面重复利用这些代码时,直接调用函数就可以了,代码简洁,思路也很清晰,下面我们就把他们放在函数里面去:

代码:var sub = Math.ceil((target-current)/1000)含义是:因为我们target-current目标时间减去当前时间,结果是毫秒数,我们这里"/1000"是换算成秒,后面方便计算天时分等,然后前面加上了Math.celi是向上取整的意思。然后下面就是求天时分秒,parseInt是舍小数取整数部分,例如:parseInt(3.87)=3;然后是计算小时的那个:var hours = parseInt(sub%(60*60*24)/(60*60)),sub%(60*60*24)是对天取余就是小时呀,然后再除以秒和小时直接的换算单位:60*60;下面的分和秒依次类推:对小时取余就是分钟、对分钟取余就是秒。最后用对象接收,返回对象。

 然后就是用下面这段代码直接输出,因为我们已经计算完多少天以及时分秒了:

document.write(`京东双11-${res.day}天${res.hours}时${res.minutes}分${res.seconds}秒`)

 (注:不懂斜引号和$()用法的可以看我上一个文章:js的ES6中的模板字符串( ``/$() )_陌一一的博客-CSDN博客

但是当一段代码写完后输出的结果是固定的天时分秒,时间都不变化的,除非我们在刷新加载一次,因为每次刷新的当前时间不一样,所以结果会不一样。那就有人疑惑了,为啥不刷新时间是不变了,因为我们刚开始定义的(var currentDate = new Date())当前时间是它代码执行到那个定义时间对象时的时间,后面就不会再变了呀,就像刻舟求剑一样,刚开始你刻的剑的地方已经不是现在剑所在的位置了,所以差值是不会变的,那需要我们不断的手动刷新重新加载获取当前的时间才会变,但是自己手动刷新太麻烦了吧,我想要让它自己变,那就需要用到间隔定时器帮我们了,让它间隔1s就获取一下当前的时间,然后打印一下差值,结果不就自己变了吗,所以就有了下面这段代码:

setInterval(function(){
            //定义返回当前时间对象
            var currentDate = new Date()
            var res = diffTime(currentDate,targetDate)
            document.write(`京东双11-${res.day}天${res.hours}时${res.minutes}分${res.seconds}秒`)
            document.write("<br>")
},1000)

我们想让它每间隔1s获取一下当前时间和差值,所以我们要把之前我们最上面定义的当前时间和获取差值的,也就是这段代码 :var currentDate = new Date()和这段代码:var res = diffTime(currentDate,targetDate)拿下来放在间隔定时器setInterval里面。

但是打印结果是这样子的:

虽然结果是在变,但它一直在界面上输出, 我想要那种动态的,在一个位置上倒计时的,下一次结果覆盖上一次结果的,这时候我们就要了解一个东西了:

 结果:

 我们写一个标签,标签身上有id选择器,然后我们输出一下这个id选择器的名称,结果如上所示,我们得到的其实是一个对象,不是一个标签了,然后我们再用这个对象去访问这个innerHTML方法,这个方法的含义就是我把一个值赋值给它,下一次再赋值就覆盖上次的值,所以我们就直接像下面这样做:

 先创建一个div标签,然后里面放id选择器,然后用:id选择器名.innerHTML去实现下一次结果覆盖上一次结果的效果。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐