JavaScript - Động hóa DOM

Xin chào các nhà phát triển web tương lai! Hôm nay, chúng ta sẽ bắt đầu một hành trình đầy thú vị vào thế giới của động hóa DOM bằng JavaScript. Như một người giáo viên khoa học máy tính gần gũi, tôi rất vui mừng được hướng dẫn các bạn qua chủ đề hấp dẫn này. Tin tôi đi, đến cuối bài học này, bạn sẽ làm cho các trang web sống động với chuyển động!

JavaScript - DOM Animation

Động hóa các phần tử DOM bằng JavaScript

Trước khi chúng ta lặn vào chi tiết của animation, hãy nhanh chóng ôn lại xem DOM là gì. DOM có nghĩa là Document Object Model, và nó cơ bản là một giao diện lập trình cho các tài liệu HTML. Nó đại diện cho cấu trúc của một tài liệu dưới dạng một cây phân cấp hình cây, cho phép chúng ta manipulabe nội dung và cấu trúc của trang web bằng JavaScript.

Bây giờ, khi chúng ta nói về việc động hóa các phần tử DOM, chúng ta đang đề cập đến việc thay đổi các thuộc tính của chúng theo thời gian để tạo ra ảo giác chuyển động hoặc biến đổi. Điều này giống như tạo ra một cuốn sách lật animation, nhưng với mã!

Hãy bắt đầu với một ví dụ đơn giản:

<div id="myBox" style="width: 100px; height: 100px; background-color: red; position: absolute;"></div>

<script>
let box = document.getElementById('myBox');
let position = 0;

function moveBox() {
    position += 1;
    box.style.left = position + 'px';
}

setInterval(moveBox, 10);
</script>

Trong ví dụ này, chúng ta đang di chuyển một hộp đỏ trên màn hình. Hãy phân tích nó:

  1. Chúng ta tạo một phần tử <div> với một số thuộc tính.style ban đầu.
  2. Chúng ta sử dụng document.getElementById('myBox') để lấy tham chiếu đến hộp của chúng ta.
  3. Chúng ta định nghĩa một hàm moveBox() rằng tăng giá trị position và cập nhật thuộc tính.style left của hộp.
  4. Chúng ta sử dụng setInterval() để gọi moveBox() mỗi 10 mili giây, tạo ra một animation mượt mà.

Động hóa các phần tử DOM bằng phương pháp setInterval()

Phương pháp setInterval() là một cách để tạo animation trong JavaScript. Nó gọi lại một hàm tại các khoảng thời gian xác định. Dưới đây là một ví dụ phức tạp hơn:

<div id="bouncer" style="width: 50px; height: 50px; background-color: blue; border-radius: 25px; position: absolute;"></div>

<script>
let bouncer = document.getElementById('bouncer');
let x = 0;
let y = 0;
let dx = 2;
let dy = 2;

function animate() {
    x += dx;
    y += dy;

    if (x > window.innerWidth - 50 || x < 0) dx = -dx;
    if (y > window.innerHeight - 50 || y < 0) dy = -dy;

    bouncer.style.left = x + 'px';
    bouncer.style.top = y + 'px';
}

setInterval(animate, 10);
</script>

Script này tạo hiệu ứng quả bóng nhảy:

  1. Chúng ta thiết lập vị trí ban đầu (x, y) và vận tốc (dx, dy).
  2. Trong hàm animate(), chúng ta cập nhật vị trí dựa trên vận tốc.
  3. Chúng ta kiểm tra xem quả bóng có va vào mép cửa sổ hay không và đảo ngược hướng nếu có.
  4. Chúng ta cập nhật vị trí của quả bóng trên màn hình.
  5. setInterval() gọi animate() mỗi 10ms, tạo ra chuyển động mượt mà.

Động hóa các phần tử DOM bằng phương pháp requestAnimationFrame()

Trong khi setInterval() hoạt động, các trình duyệt hiện đại cung cấp một phương pháp hiệu quả hơn: requestAnimationFrame(). Phương pháp này cho biết bạn muốn thực hiện một animation và yêu cầu trình duyệt gọi một hàm để cập nhật animation trước mỗi lần vẽ lại.

Hãy viết lại quả bóng nhảy sử dụng requestAnimationFrame():

<div id="bouncer" style="width: 50px; height: 50px; background-color: green; border-radius: 25px; position: absolute;"></div>

<script>
let bouncer = document.getElementById('bouncer');
let x = 0;
let y = 0;
let dx = 2;
let dy = 2;

function animate() {
    x += dx;
    y += dy;

    if (x > window.innerWidth - 50 || x < 0) dx = -dx;
    if (y > window.innerHeight - 50 || y < 0) dy = -dy;

    bouncer.style.left = x + 'px';
    bouncer.style.top = y + 'px';

    requestAnimationFrame(animate);
}

requestAnimationFrame(animate);
</script>

Sự khác biệt chính ở đây là thay vì sử dụng setInterval(), chúng ta gọi requestAnimationFrame(animate) ở cuối hàm animate(). Điều này tạo ra một vòng lặp mà trình duyệt gọi animate() ngay trước mỗi lần vẽ lại.

Động hóa các phần tử DOM bằng cách thay đổi các thuộc tính CSS

Đến nay, chúng ta đã thay đổi các thuộc tính CSS trực tiếp bằng JavaScript. Tuy nhiên, phát triển web hiện đại thường sử dụng các transition và animation CSS để có hiệu suất mượt mà hơn. Hãy xem cách chúng ta có thể kích hoạt animation CSS bằng JavaScript:

<style>
.box {
    width: 100px;
    height: 100px;
    background-color: purple;
    position: absolute;
    transition: all 0.5s ease;
}
</style>

<div id="myBox" class="box"></div>

<script>
let box = document.getElementById('myBox');
let position = 0;

function moveBox() {
    position += 50;
    box.style.transform = `translateX(${position}px)`;

    if (position < 200) {
        requestAnimationFrame(moveBox);
    }
}

box.addEventListener('click', function() {
    position = 0;
    requestAnimationFrame(moveBox);
});
</script>

Trong ví dụ này:

  1. Chúng ta định nghĩa một lớp CSS với thuộc tính transition.
  2. Hàm JavaScript của chúng ta thay đổi thuộc tính transform thay vì left.
  3. Chúng ta sử dụng requestAnimationFrame() để tạo animation mượt mà.
  4. Animation bắt đầu khi hộp được nhấp.

Phương pháp này thường tạo ra animation mượt mà hơn vì trình duyệt có thể tối ưu hóa các transition CSS.

Dưới đây là bảng tóm tắt các phương pháp chúng ta đã thảo luận:

Phương pháp Ưu điểm Nhược điểm
setInterval() Dễ hiểu và triển khai Có thể ít hiệu quả, gây ra jank
requestAnimationFrame() Hiệu quả hơn, đồng bộ với tần số làm mới của trình duyệt Nhẹ nhàng phức tạp hơn để triển khai
CSS Transitions Rất mượt mà, có thể được tăng tốc phần cứng Điều khiển ít hơn về các bước animation

Nhớ rằng, animation có thể làm tăng trải nghiệm người dùng, nhưng nó nên được sử dụng một cách khiêm tốn. Quá nhiều animation có thể làm rối loạn hoặc thậm chí gây ra cảm giác say sóng cho một số người dùng.

Đó là tất cả cho hành trình của chúng ta vào động hóa DOM bằng JavaScript! Tôi hy vọng bạn đã thưởng thức bài học này như tôi đã thưởng thức việc dạy nó. Hãy tiếp tục thực hành, tiếp tục animation, và quan trọng nhất, hãy vui vẻ với mã!

Credits: Image by storyset