Day30 -- Countdown Clock

目标

今天要来做的是倒数计时器

Step1

let countdown;

function timer(seconds) {
    const now = Date.now();
    const then = now + seconds * 1000;
    displayTimeLeft(seconds);

    countdown = setInterval(() => {
        const secondsLeft = Math.round((then - Date.now())/1000);
        if (secondsLeft < 0) {
            clearInterval(countdown);
            return
        }
        displayTimeLeft(secondsLeft);
    }, 1000)
}

function displayTimeLeft(seconds) {
    console.log(seconds);
}

今天先不选定元素,先来处理计时器

首先,以Date.now()取得现在的时间,并且计算计时器结束的时间

然後每过一段时间(1秒),要重新计算一次剩余的秒数,如果剩余秒数小於0,则停止计算

这边再加上一个displayTimeLeft函式,用於显示时间

Date.now()

此方法回传自 1970/01/01 00:00:00 UTC 起经过的毫秒数

WindowOrWorkerGlobalScope.clearInterval()

此方法用於取消setInterval()设置的动作

Step2

const timerDisplay = document.querySelector('.display__time-left')

function displayTimeLeft(seconds) {
    const hours = Math.floor(seconds / 3600);
    const mins = Math.floor((seconds % 3600) / 60);
    const secs = (seconds % 3600) % 60
    const display = `${hours < 10 ? '0' : ''}${hours}:${mins < 10 ? '0' : ''}${mins}:${secs < 10 ? '0' : ''}${secs}`
    timerDisplay.textContent = display;
    document.title = display;
}

接下来,选定显示的元素,然後计算出倒数的时、分、秒後设为元素的文字内容

这边还可以透过document.title设定<title>

Step3

const endTime = document.querySelector('.display__end-time');

function displayEndTime(timestamp) {
    const end = new Date(timestamp);
    const hour = end.getHours();
    const minutes = end.getMinutes();
    endTime.textContent = `Be Back At ${hour < 10 ? '0' : ''}${hour}:${minutes < 10 ? '0' : ''}${minutes}`;  
}

这边要计算倒数结束的时间为何,我们可以透过Date物件转换秒数成可读性较高的时间格式

Countdown%20Clock%208e2acbb8f2f4471cb5fa6d4629607ffe/_2020-10-14_00.12.59.png

Date

建立一个 JavaScript Date 物件来指向某一个时间点,Date 物件是基於世界标准时间(UTC) 1970 年 1 月 1 日开始的毫秒数值来储存时间

Step4

const buttons = document.querySelectorAll('[data-time]');

function startTimer() {
    const seconds = parseInt(this.dataset.time);
    timer(seconds);
}
  
buttons.forEach(button => button.addEventListener('click', startTimer));

这边要处理的是画面顶部的按钮,每当我们点击一次,就要启动一个计时器,但是同时也要取消先前启动的计时器

function timer(seconds) {
    // clear any existing timers
    clearInterval(countdown);
		// ...
}

Countdown%20Clock%208e2acbb8f2f4471cb5fa6d4629607ffe/_2020-10-14_00.12.59%201.png

Step5

document.customForm.addEventListener('submit', function(e) {
    e.preventDefault();
    const mins = this.minutes.value;
    console.log(mins);
    timer(mins * 60);
    this.reset();
});

最後这边要来做的是自订时间长度

当元素有name属性,我们可以直接透过name选到想要的元素,不用再透过querySelector()

後记

这是JS30的第29天,但是是我第30篇正文,接下来会继续完成挑战,然後再补个心得
不过我昨天就铁人链成了ㄏㄏ


<<:  Day 29 - Summary

>>:  谁温暖了资安部-28(破口)

Day02 测试写起乃 - Rails 测试推荐资源

在开始之前我想先推荐几个来源对於写 Rails 测试颇有帮助的几个网站也是我个人在开始写之前有看过的...

[Day27] 使用POSTMAN测试

Get 使用get方法取得index函数回传资料 新增 使用post方式将表单传入 修改 使用put...

【Day 21】Algorithm - Find Cycle in Directed Graph

这题真的需要花一点功夫,题目并不难懂,但是不能用直观的方式去写,可以上网搜寻关键字「find cyc...

人脸辨识-day17 应用层面--3

除了上述的应用,目前因人脸辨识技术的持续进步,使用人脸侦测时可以将五官抓出,来分析脸上五官的点,利用...

Consistency and Consensus (2-1) - Linearizability

Linearizability 线性一致性 (Linearizability) 的概念就是原来有多份...