Thứ tư, 21/10/2020 | 00:00 GMT+7

Xây dựng Đồng hồ đếm ngược trong JavaScript


Đồng hồ đếm ngược có thể phục vụ nhiều mục đích. Họ có thể thông báo cho user biết họ đã làm điều gì đó bao lâu hoặc bao lâu cho đến khi một số sự kiện xảy ra, chẳng hạn như sự ra mắt của trang web mới của bạn.

Trong bối cảnh bán hàng và tiếp thị, chúng được dùng để tạo cảm giác cấp bách nhằm khuyến khích chuyển đổi. FOMO có thể khó bị đánh bại, nhưng việc xây dựng đồng hồ đếm ngược bằng JavaScript thuần túy rất dễ dàng!

Bắt đầu

Vì ta đang tận dụng sức mạnh của JavaScript ở dạng thuần túy nhất, không có bất kỳ thư viện front-end nào, nên không cần phải thực hiện hàng tấn bootstrapping.

Tất cả những gì ta cần là một file .html<div> để đưa kết quả của bộ đếm thời gian đếm ngược vào và một khối <script> sẽ chứa mã của ta :

<!DOCTYPE html>
<html>
  <body>
    <div id="countdown"></div>
    <script>
      // This is where our sweet timer code will go!
    </script>
  </body>
</html>

Tính thời gian còn lại

Để tính thời gian còn lại, ta cần tìm sự khác biệt giữa thời gian hiện tại và thời gian mà đồng hồ đếm ngược của ta sẽ hết hạn. Một trong những thời điểm đáng chú ý hơn mà ta đếm ngược là Ngày đầu năm mới, vì vậy ta sẽ sử dụng năm mới sắp tới làm thời gian kết thúc:

const difference = +new Date("2020-01-01") - +new Date();

Dấu + trước new Date là viết tắt để yêu cầu JavaScript truyền đối tượng dưới dạng số nguyên, cung cấp cho ta dấu thời gian Unix của đối tượng được biểu thị dưới dạng micro giây kể từ kỷ nguyên.

Định dạng thành Ngày, Giờ, Phút và Giây

Bây giờ ta đã biết tổng số mili giây cho đến khi hết thời gian đếm ngược, ta cần chuyển đổi số mili giây thành một thứ gì đó thân thiện hơn và con người dễ đọc hơn một chút.

Ta sẽ tính toán tổng số giờ, phút và tất nhiên, giây, bằng cách thực hiện một số phép toán và sử dụng toán tử modulus % :

const parts = {
  days: Math.floor(difference / (1000 * 60 * 60 * 24)),
  hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
  minutes: Math.floor((difference / 1000 / 60) % 60),
  seconds: Math.floor((difference / 1000) % 60),
};

Bằng cách làm tròn các số xuống, ta có thể giảm phần còn lại để nhận được giá trị toàn bộ số.

Với một đối tượng có đầy đủ ngày, giờ, phút và giây còn lại, ta có thể ghép các thứ lại với nhau thành một chuỗi:

const remaining = Object.keys(parts)
  .map((part) => {
    if (!parts[part]) return;
    return `${parts[part]} ${part}`;
  })
  .join(" ");

Hiển thị thời gian còn lại trên trang

Với các phần thời gian được tập hợp thành một chuỗi, ta có thể cập nhật <div> mình để chứa giá trị:

document.getElementById("countdown").innerHTML = remaining;

Tự động cập nhật bộ hẹn giờ

Lúc này, ta đã tính toán chênh lệch thời gian giữa thời gian hiện tại và thời gian mà bộ đếm ngược của ta hết hạn. Ta đã chia thời gian đó thành giờ, phút và giây, sau đó cập nhật trang với thời gian còn lại.

Rồi thời gian đứng yên.

Nếu không có logic bổ sung để cập nhật trang định kỳ, bộ hẹn giờ sẽ bị kẹt ở vị trí cho đến lần tải trang tiếp theo. Nếu không có bản cập nhật, thật khó để mô tả nó như một bộ đếm thời gian.

Không có vấn đề gì lớn, ta có thể dễ dàng tạo khoảng thời gian để chạy mỗi giây (hoặc 1000 mili giây) và cập nhật hiển thị của bộ hẹn giờ:

setInterval(() => {
  // This is where we'd recalculate the time remaining
}, 1000);

Để tất cả chúng cùng nhau

Rõ ràng là ví dụ cuối cùng là một chút thiếu sót. Đó là bởi vì đã đến lúc kết hợp tất cả lại với nhau thành một thứ có thể sử dụng được và thậm chí thêm một số tính năng bổ sung như cập nhật bộ đếm thời gian khi tải trang (thay vì đợi khoảng thời gian chạy đầu tiên) và xử lý mọi thứ khi bộ hẹn giờ đã hết hạn:

<!DOCTYPE html>
<html>
  <body>
    <div id="countdown"></div>
    <script>
      function countdownTimer() {
        const difference = +new Date("2020-01-01") - +new Date();
        let remaining = "Time's up!";

        if (difference > 0) {
          const parts = {
            days: Math.floor(difference / (1000 * 60 * 60 * 24)),
            hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
            minutes: Math.floor((difference / 1000 / 60) % 60),
            seconds: Math.floor((difference / 1000) % 60)
          };

          remaining = Object.keys(parts)
            .map(part => {
              if (!parts[part]) return;
              return `${parts[part]} ${part}`;
            })
            .join(" ");
        }

        document.getElementById("countdown").innerHTML = remaining;
      }

      countdownTimer();
      setInterval(countdownTimer, 1000);
    </script>
  </body>
</html>

Bạn có thể kiểm tra một ví dụ hoạt động của mã này trên CodeSandbox .


Tags:

Các tin trước

Giới thiệu về Thị giác máy tính trong JavaScript sử dụng OpenCV.js 2020-10-20
Thêm, loại bỏ & chuyển đổi lớp với classList trong JavaScript 2020-10-13
Cách Chèn Javascript vào HTML bằng Thẻ script 2020-09-23
Mẫu thiết kế module trong JavaScript 2020-09-21
Mẫu thiết kế trình quan sát trong JavaScript 2020-09-21
Mẫu thiết kế Singleton trong JavaScript 2020-09-21
Mẫu thiết kế nguyên mẫu trong JavaScript 2020-09-21
Lời hứa của JavaScript dành cho người giả 2020-09-15
Sao chép các đối tượng trong JavaScript 2020-09-15
Cách sử dụng API tìm nạp JavaScript để lấy dữ liệu 2020-09-15