Các ví dụ về AJAX về thực tế trong JavaScript

Javascript nâng cao | by Học Javascript

Trong thời đại phát triển mạnh mẽ của các ứng dụng web tương tác, người dùng ngày càng kỳ vọng vào những trải nghiệm mượt mà, nhanh chóng và tiện lợi. Một trong những công nghệ cốt lõi giúp hiện thực hóa điều đó chính là AJAX (Asynchronous JavaScript and XML). Thay vì phải tải lại toàn bộ trang mỗi khi người dùng thao tác, AJAX cho phép gửi và nhận dữ liệu từ server một cách bất đồng bộ, từ đó nâng cao hiệu suất và cải thiện trải nghiệm người dùng rõ rệt.

Trong JavaScript, AJAX không chỉ là một khái niệm kỹ thuật mà còn là công cụ thiết yếu để xây dựng các tính năng hiện đại như tìm kiếm gợi ý, nạp nội dung động, gửi form không tải lại trang, và rất nhiều ứng dụng thực tế khác. Bài viết này sẽ giới thiệu những ví dụ cụ thể, gần gũi và dễ triển khai giúp bạn hiểu rõ hơn cách ứng dụng AJAX trong lập trình JavaScript một cách hiệu quả và chuyên nghiệp.

Tổng quan ngắn về cách hoạt động của AJAX trong JavaScript

AJAX (Asynchronous JavaScript and XML) là một kỹ thuật cho phép các trang web giao tiếp với máy chủ và lấy dữ liệu mà không cần tải lại trang. Cách hoạt động của AJAX có thể được chia thành ba bước chính:

Gửi yêu cầu bất đồng bộ từ client đến server

Khi người dùng thực hiện một thao tác trên giao diện người dùng (ví dụ: nhấp vào nút, thay đổi một ô nhập liệu, cuộn trang), JavaScript sẽ gửi một yêu cầu đến máy chủ để lấy hoặc gửi dữ liệu. Yêu cầu này được gửi một cách bất đồng bộ (asynchronously), có nghĩa là giao diện người dùng vẫn tiếp tục hoạt động mà không bị gián đoạn.

Có hai phương pháp chính để gửi yêu cầu AJAX:

  • XMLHttpRequest (XHR): Đây là phương pháp cổ điển, được sử dụng phổ biến trong các ứng dụng trước khi Fetch API ra đời. Với XMLHttpRequest, chúng ta tạo một đối tượng XHR, thiết lập loại yêu cầu (GET, POST), URL và gửi yêu cầu.

  • Fetch API: Đây là phương pháp hiện đại hơn, được phát triển để thay thế XMLHttpRequest, với cú pháp đơn giản và hỗ trợ Promise. Fetch API cho phép gửi yêu cầu HTTP và xử lý phản hồi bằng cách sử dụng .then().catch().

Ví dụ về gửi yêu cầu bằng Fetch API:

fetch('https://api.example.com/data')
  .then(response => response.json())  // Phản hồi được chuyển thành JSON
  .then(data => console.log(data))    // Dữ liệu nhận được
  .catch(error => console.error('Lỗi:', error));

Server xử lý yêu cầu và trả về dữ liệu

Khi máy chủ nhận được yêu cầu từ client, nó sẽ xử lý yêu cầu đó (có thể truy vấn cơ sở dữ liệu, thực hiện tính toán, hoặc các thao tác khác) và trả lại một phản hồi. Phản hồi này có thể ở nhiều định dạng khác nhau, nhưng phổ biến nhất là:

  • JSON: Định dạng dữ liệu nhẹ, dễ dàng sử dụng với JavaScript nhờ phương thức JSON.parse()JSON.stringify().

  • XML: Mặc dù ít phổ biến hơn JSON trong các ứng dụng hiện đại, XML vẫn được sử dụng trong một số hệ thống cũ hoặc API.

  • Text: Đối với những dữ liệu không cần cấu trúc như thông báo đơn giản hoặc giá trị trả về từ server.

Một ví dụ về phản hồi JSON từ server:

{
  "status": "success",
  "message": "Dữ liệu đã được cập nhật"
}

JavaScript nhận phản hồi và cập nhật nội dung trang mà không cần reload

Sau khi server trả về dữ liệu, JavaScript trên client sẽ nhận được phản hồi và tiếp tục xử lý. Tùy thuộc vào loại dữ liệu (JSON, XML, hoặc text), JavaScript có thể cập nhật nội dung trang mà không cần tải lại trang (refresh). Điều này mang lại trải nghiệm người dùng mượt mà và tiết kiệm băng thông, vì chỉ các phần cần thiết của trang mới được thay đổi.

Ví dụ: Nếu nhận được dữ liệu JSON từ server, bạn có thể cập nhật giao diện người dùng như sau:

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    // Cập nhật nội dung trang bằng dữ liệu nhận được
    document.getElementById('result').innerHTML = data.message;
  })
  .catch(error => console.error('Lỗi:', error));

Trong ví dụ trên, sau khi nhận được phản hồi JSON, JavaScript sẽ sử dụng dữ liệu để cập nhật phần tử có id result trên trang mà không cần phải tải lại toàn bộ trang web.

Gửi form không cần tải lại trang trong JavaScript

Trong ví dụ này, chúng ta sẽ tạo một form đăng ký hoặc liên hệ và sử dụng AJAX để gửi thông tin mà không cần tải lại trang. Việc này giúp trải nghiệm người dùng trở nên mượt mà hơn, giảm thiểu thời gian chờ đợi và không làm gián đoạn tương tác của người dùng với trang web.

Các bước thực hiện:

HTML form

Trước tiên, ta tạo một form cơ bản trong HTML, nơi người dùng có thể điền thông tin và gửi đi mà không cần phải tải lại trang. Ví dụ, đây là form đăng ký thông tin người dùng:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Đăng ký</title>
</head>
<body>
    <h2>Đăng ký người dùng</h2>
    <form id="registrationForm">
        <label for="name">Họ và tên:</label><br>
        <input type="text" id="name" name="name" required><br><br>

        <label for="email">Email:</label><br>
        <input type="email" id="email" name="email" required><br><br>

        <label for="message">Thông điệp:</label><br>
        <textarea id="message" name="message" required></textarea><br><br>

        <button type="submit">Gửi</button>
    </form>

    <div id="responseMessage"></div>

    <script src="app.js"></script>
</body>
</html>

Ở đây, form có ba trường thông tin: Họ và tên, Email và Thông điệp. Khi người dùng nhấn nút "Gửi", dữ liệu sẽ được gửi qua AJAX thay vì tải lại trang.

JavaScript gửi dữ liệu bằng phương thức POST

Tiếp theo, chúng ta sẽ sử dụng JavaScript và AJAX (qua Fetch API hoặc XMLHttpRequest) để gửi dữ liệu từ form tới server. Sau khi form được gửi, dữ liệu sẽ được gửi tới server mà không cần tải lại trang.

Dưới đây là mã JavaScript sử dụng Fetch API để gửi dữ liệu từ form:

document.getElementById('registrationForm').addEventListener('submit', function(event) {
    event.preventDefault();  // Ngăn chặn hành động mặc định (tải lại trang)

    // Lấy dữ liệu từ form
    const formData = new FormData(this);

    // Gửi dữ liệu tới server bằng Fetch API (phương thức POST)
    fetch('processForm.php', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())  // Xử lý phản hồi từ server dưới dạng JSON
    .then(data => {
        // Hiển thị thông báo thành công/thất bại
        const responseMessage = document.getElementById('responseMessage');
        if (data.status === 'success') {
            responseMessage.innerHTML = `<p style="color: green;">${data.message}</p>`;
        } else {
            responseMessage.innerHTML = `<p style="color: red;">${data.message}</p>`;
        }
    })
    .catch(error => {
        console.error('Lỗi:', error);
    });
});

Giải thích mã JavaScript:

  • event.preventDefault(): Ngừng hành động mặc định của form (tải lại trang).

  • FormData(this): Thu thập tất cả dữ liệu từ form và chuẩn bị chúng cho việc gửi đi.

  • fetch('processForm.php', {...}): Gửi dữ liệu tới server bằng phương thức POST. Dữ liệu được gửi dưới dạng FormData, giúp dễ dàng xử lý trên server mà không cần phải chuyển đổi.

  • response.json(): Server trả về dữ liệu dưới dạng JSON, và JavaScript sẽ xử lý phản hồi này.

  • Cập nhật giao diện: Sau khi nhận được phản hồi từ server, JavaScript sẽ hiển thị thông báo thành công hoặc thất bại trong phần tử #responseMessage.

PHP/Node.js nhận dữ liệu, xử lý, và trả kết quả

Ở phía server, chúng ta sẽ sử dụng PHP hoặc Node.js để xử lý dữ liệu nhận được từ client. Ví dụ dưới đây sử dụng PHP để nhận và xử lý dữ liệu từ form.

PHP (processForm.php):

<?php
header('Content-Type: application/json');  // Đảm bảo phản hồi là JSON

// Kiểm tra xem dữ liệu đã được gửi qua POST chưa
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Lấy dữ liệu từ form
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];

    // Xử lý dữ liệu (ví dụ: lưu vào cơ sở dữ liệu, gửi email, v.v.)
    // Ở đây, ta chỉ kiểm tra xem dữ liệu có hợp lệ không
    if (empty($name) || empty($email) || empty($message)) {
        echo json_encode(['status' => 'error', 'message' => 'Vui lòng điền đầy đủ thông tin.']);
    } else {
        echo json_encode(['status' => 'success', 'message' => 'Thông tin của bạn đã được gửi thành công!']);
    }
}
?>

Giải thích mã PHP:

  • $_POST: Lấy dữ liệu gửi từ client qua phương thức POST.

  • json_encode(): Trả về phản hồi dưới dạng JSON. Dữ liệu JSON này sẽ được JavaScript xử lý và hiển thị cho người dùng.

JavaScript hiển thị thông báo thành công/thất bại

Sau khi nhận được phản hồi từ server, JavaScript sẽ kiểm tra giá trị của trường status trong dữ liệu JSON và hiển thị thông báo phù hợp.

  • Nếu statussuccess, sẽ hiển thị thông báo màu xanh với nội dung "Thông tin của bạn đã được gửi thành công!".

  • Nếu statuserror, sẽ hiển thị thông báo màu đỏ với nội dung "Vui lòng điền đầy đủ thông tin."

Kiểm tra tên người dùng trùng khi đăng ký trong JavaScript

Trong ví dụ này, chúng ta sẽ sử dụng AJAX để kiểm tra tên người dùng khi người dùng nhập vào ô đăng ký, giúp người dùng biết ngay liệu tên họ chọn đã tồn tại trong cơ sở dữ liệu hay chưa mà không cần phải gửi toàn bộ form. Điều này giúp cải thiện trải nghiệm người dùng và giảm thiểu thời gian phản hồi.

Các bước thực hiện:

HTML: Tạo form đăng ký

Chúng ta sẽ tạo một form đơn giản với ô nhập tên người dùng và một trường nhập email. Khi người dùng gõ tên người dùng vào ô input, hệ thống sẽ tự động kiểm tra xem tên người dùng đó đã tồn tại trong cơ sở dữ liệu hay chưa.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Đăng ký người dùng</title>
</head>
<body>
    <h2>Đăng ký tài khoản</h2>
    <form id="registrationForm">
        <label for="username">Tên người dùng:</label><br>
        <input type="text" id="username" name="username" required><br>
        <span id="usernameResponse" style="color: red;"></span><br><br>

        <label for="email">Email:</label><br>
        <input type="email" id="email" name="email" required><br><br>

        <button type="submit">Đăng ký</button>
    </form>

    <script src="app.js"></script>
</body>
</html>

Trong form này, chúng ta có trường "Tên người dùng" (username). Khi người dùng gõ vào ô này, chúng ta sẽ kiểm tra tên người dùng đó có tồn tại trong cơ sở dữ liệu hay không. Nếu tên đã tồn tại, hệ thống sẽ thông báo ngay lập tức.

JavaScript: Gửi yêu cầu AJAX khi người dùng gõ

Sử dụng sự kiện onkeyup hoặc onblur của ô input để gửi yêu cầu AJAX tới server để kiểm tra tên người dùng. Dưới đây là cách sử dụng onkeyup để gửi yêu cầu khi người dùng nhập vào ô input.

document.getElementById('username').addEventListener('keyup', function() {
    const username = this.value;

    // Kiểm tra nếu tên người dùng không trống
    if (username.length > 0) {
        // Gửi yêu cầu AJAX để kiểm tra tên người dùng
        fetch('checkUsername.php?username=' + encodeURIComponent(username))
            .then(response => response.json())
            .then(data => {
                const responseMessage = document.getElementById('usernameResponse');
                if (data.status === 'exists') {
                    responseMessage.innerHTML = 'Tên người dùng này đã tồn tại.';
                } else {
                    responseMessage.innerHTML = 'Tên người dùng này có thể sử dụng.';
                }
            })
            .catch(error => {
                console.error('Lỗi:', error);
            });
    } else {
        document.getElementById('usernameResponse').innerHTML = '';  // Nếu ô trống, xóa thông báo
    }
});

Giải thích mã JavaScript:

  • onkeyup: Được sử dụng để bắt sự kiện khi người dùng gõ vào ô input "Tên người dùng". Mỗi lần người dùng gõ một ký tự, sự kiện này sẽ được kích hoạt.

  • fetch(): Gửi yêu cầu tới file PHP checkUsername.php với tham số username được mã hóa (dùng encodeURIComponent để đảm bảo không có ký tự đặc biệt trong URL).

  • response.json(): Dữ liệu trả về từ server dưới dạng JSON, sẽ được phân tích và hiển thị cho người dùng.

  • Hiển thị kết quả: Nếu tên người dùng đã tồn tại, hiển thị thông báo "Tên người dùng này đã tồn tại." Nếu không, hiển thị "Tên người dùng này có thể sử dụng."

PHP: Kiểm tra tên người dùng trong cơ sở dữ liệu

Bây giờ, chúng ta cần tạo một file PHP checkUsername.php để kiểm tra tên người dùng trong cơ sở dữ liệu. Đây là mã PHP đơn giản để làm việc này:

PHP (checkUsername.php):

<?php
header('Content-Type: application/json');  // Đảm bảo phản hồi là JSON

// Lấy tên người dùng từ query string
if (isset($_GET['username'])) {
    $username = $_GET['username'];

    // Kết nối với cơ sở dữ liệu (thay đổi các thông tin kết nối cho phù hợp)
    $conn = new mysqli('localhost', 'root', '', 'your_database');

    // Kiểm tra kết nối
    if ($conn->connect_error) {
        die("Kết nối thất bại: " . $conn->connect_error);
    }

    // Truy vấn cơ sở dữ liệu để kiểm tra tên người dùng
    $sql = "SELECT * FROM users WHERE username = '$username'";
    $result = $conn->query($sql);

    // Kiểm tra nếu tên người dùng đã tồn tại
    if ($result->num_rows > 0) {
        // Nếu tên người dùng đã tồn tại
        echo json_encode(['status' => 'exists']);
    } else {
        // Nếu tên người dùng chưa tồn tại
        echo json_encode(['status' => 'available']);
    }

    // Đóng kết nối
    $conn->close();
}
?>

Giải thích mã PHP:

  • $_GET['username']: Lấy giá trị tên người dùng từ URL (truyền từ JavaScript).

  • Kết nối cơ sở dữ liệu: Dùng mysqli để kết nối với cơ sở dữ liệu và thực hiện truy vấn kiểm tra xem tên người dùng có tồn tại trong bảng users hay không.

  • Trả về kết quả dưới dạng JSON: Trả về JSON với thông tin statusexists nếu tên người dùng đã tồn tại, hoặc available nếu tên chưa tồn tại.

Kết quả và hiển thị phản hồi

Khi người dùng nhập tên vào ô input, JavaScript sẽ gửi yêu cầu AJAX đến server. Server sẽ trả về JSON và thông báo sẽ được hiển thị ngay trên trang web. Nếu tên người dùng đã tồn tại trong cơ sở dữ liệu, người dùng sẽ nhận được thông báo "Tên người dùng này đã tồn tại." Nếu tên có thể sử dụng, sẽ hiển thị thông báo "Tên người dùng này có thể sử dụng."

Gợi ý tìm kiếm (Autocomplete) trong JavaScript

Chức năng Autocomplete (gợi ý tìm kiếm) giúp người dùng tiết kiệm thời gian bằng cách hiển thị danh sách các từ khóa hoặc kết quả tìm kiếm ngay khi họ bắt đầu gõ. Trong ví dụ này, chúng ta sẽ sử dụng AJAX để gửi từ khóa tìm kiếm tới server và nhận về các gợi ý tìm kiếm mà không cần phải tải lại trang. Sau đó, JavaScript sẽ hiển thị danh sách các gợi ý này dưới ô nhập liệu.

Các bước thực hiện:

HTML: Tạo form tìm kiếm

Trước tiên, chúng ta tạo một form đơn giản với một ô input cho người dùng nhập từ khóa tìm kiếm.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Gợi ý tìm kiếm</title>
    <style>
        .autocomplete-suggestions {
            border: 1px solid #ccc;
            max-height: 150px;
            overflow-y: auto;
            position: absolute;
            background-color: white;
            width: 200px;
            z-index: 9999;
        }
        .autocomplete-suggestion {
            padding: 10px;
            cursor: pointer;
        }
        .autocomplete-suggestion:hover {
            background-color: #f0f0f0;
        }
    </style>
</head>
<body>
    <h2>Tìm kiếm sản phẩm</h2>
    <input type="text" id="searchInput" placeholder="Nhập từ khóa tìm kiếm..." autocomplete="off">
    <div id="suggestionsBox" class="autocomplete-suggestions"></div>

    <script src="app.js"></script>
</body>
</html>

Trong phần HTML này:

  • Chúng ta có một ô input cho người dùng nhập từ khóa tìm kiếm.

  • #suggestionsBox là phần tử sẽ hiển thị các gợi ý tìm kiếm.

JavaScript: Gửi yêu cầu AJAX khi người dùng gõ

Khi người dùng nhập vào ô tìm kiếm, JavaScript sẽ gửi yêu cầu AJAX tới server để lấy danh sách các từ khóa hoặc kết quả tìm kiếm phù hợp. Sau khi nhận được dữ liệu từ server, JavaScript sẽ hiển thị các gợi ý dưới ô input.

document.getElementById('searchInput').addEventListener('input', function() {
    const query = this.value;

    // Nếu từ khóa rỗng, không gửi yêu cầu
    if (query.length > 0) {
        // Gửi yêu cầu AJAX để lấy gợi ý
        fetch('searchSuggestions.php?q=' + encodeURIComponent(query))
            .then(response => response.json())
            .then(data => {
                const suggestionsBox = document.getElementById('suggestionsBox');
                suggestionsBox.innerHTML = ''; // Xóa gợi ý cũ

                // Hiển thị các gợi ý tìm kiếm
                data.forEach(item => {
                    const suggestionItem = document.createElement('div');
                    suggestionItem.classList.add('autocomplete-suggestion');
                    suggestionItem.innerText = item;
                    suggestionItem.onclick = function() {
                        document.getElementById('searchInput').value = item;
                        suggestionsBox.innerHTML = '';  // Ẩn gợi ý khi chọn
                    };
                    suggestionsBox.appendChild(suggestionItem);
                });
            })
            .catch(error => {
                console.error('Lỗi:', error);
            });
    } else {
        // Nếu từ khóa trống, ẩn gợi ý
        document.getElementById('suggestionsBox').innerHTML = '';
    }
});

Giải thích mã JavaScript:

  • Sự kiện input: Được sử dụng để bắt sự kiện mỗi khi người dùng nhập vào ô tìm kiếm. Mỗi lần người dùng thay đổi nội dung ô input, sự kiện này sẽ được gọi.

  • fetch(): Sử dụng phương thức fetch để gửi yêu cầu tới file PHP searchSuggestions.php, truyền từ khóa tìm kiếm qua URL (query string). Dữ liệu trả về sẽ được phân tích thành JSON.

  • Hiển thị gợi ý: Khi dữ liệu trả về, JavaScript sẽ hiển thị các gợi ý trong hộp gợi ý. Mỗi gợi ý có thể được nhấp chuột để điền vào ô tìm kiếm và ẩn hộp gợi ý.

PHP: Xử lý tìm kiếm và trả về kết quả gợi ý

Bây giờ, chúng ta cần tạo một file PHP searchSuggestions.php để xử lý yêu cầu tìm kiếm và trả về danh sách các gợi ý từ cơ sở dữ liệu hoặc một mảng mẫu.

PHP (searchSuggestions.php):

<?php
header('Content-Type: application/json'); // Đảm bảo phản hồi là JSON

if (isset($_GET['q'])) {
    $query = $_GET['q'];

    // Kết nối cơ sở dữ liệu (thay đổi thông tin kết nối cho phù hợp)
    $conn = new mysqli('localhost', 'root', '', 'your_database');

    // Kiểm tra kết nối
    if ($conn->connect_error) {
        die("Kết nối thất bại: " . $conn->connect_error);
    }

    // Truy vấn cơ sở dữ liệu để tìm các sản phẩm có tên chứa từ khóa
    $sql = "SELECT name FROM products WHERE name LIKE '%$query%'";
    $result = $conn->query($sql);

    $suggestions = [];

    if ($result->num_rows > 0) {
        // Lấy tất cả các kết quả tìm kiếm
        while ($row = $result->fetch_assoc()) {
            $suggestions[] = $row['name'];
        }
    }

    // Trả về gợi ý dưới dạng JSON
    echo json_encode($suggestions);

    // Đóng kết nối
    $conn->close();
}
?>

Giải thích mã PHP:

  • $_GET['q']: Lấy từ khóa tìm kiếm từ query string.

  • Truy vấn cơ sở dữ liệu: Sử dụng SQL LIKE để tìm kiếm các sản phẩm có tên chứa từ khóa nhập vào.

  • Trả về kết quả dưới dạng JSON: Các kết quả tìm kiếm (tên sản phẩm) sẽ được trả về dưới dạng mảng JSON để JavaScript có thể xử lý và hiển thị.

  • Kết nối cơ sở dữ liệu: Sử dụng mysqli để kết nối và truy vấn cơ sở dữ liệu.

Kết quả và hiển thị gợi ý

Khi người dùng bắt đầu gõ từ khóa tìm kiếm, JavaScript sẽ gửi yêu cầu AJAX đến server. Server sẽ trả về một danh sách các kết quả tìm kiếm phù hợp dưới dạng JSON. JavaScript nhận dữ liệu và hiển thị các gợi ý dưới ô input. Người dùng có thể chọn một gợi ý và ô input sẽ tự động điền từ khóa đã chọn.

Nạp thêm bài viết/bình luận (Load More / Infinite Scroll) trong JavaScript

Chức năng Load More hoặc Infinite Scroll cho phép người dùng tải thêm nội dung (như bài viết, bình luận) khi cuộn trang đến cuối hoặc khi nhấp vào nút "Tải thêm". Việc sử dụng AJAX giúp tải dữ liệu một cách bất đồng bộ, không cần phải tải lại toàn bộ trang, giúp cải thiện trải nghiệm người dùng.

Các bước thực hiện:

HTML: Tạo giao diện với nút "Tải thêm"

Đầu tiên, chúng ta tạo giao diện HTML với các bài viết/bình luận và một nút "Tải thêm" ở cuối trang.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Load More Posts</title>
    <style>
        .post {
            border: 1px solid #ccc;
            padding: 15px;
            margin-bottom: 10px;
        }
        #loadMoreButton {
            padding: 10px 20px;
            background-color: #28a745;
            color: white;
            border: none;
            cursor: pointer;
        }
        #loadMoreButton:hover {
            background-color: #218838;
        }
    </style>
</head>
<body>
    <h2>Bài viết</h2>

    <div id="postsContainer">
        <!-- Các bài viết sẽ được nạp vào đây -->
    </div>

    <!-- Nút Tải thêm -->
    <button id="loadMoreButton">Tải thêm</button>

    <script src="app.js"></script>
</body>
</html>

Trong phần HTML này:

  • #postsContainer là nơi các bài viết sẽ được hiển thị.

  • Nút "Tải thêm" sẽ được sử dụng để tải thêm bài viết khi người dùng nhấp vào.

JavaScript: Xử lý yêu cầu AJAX và hiển thị nội dung

JavaScript sẽ xử lý sự kiện khi người dùng cuộn trang đến cuối hoặc khi họ nhấp vào nút "Tải thêm". Khi đó, một yêu cầu AJAX sẽ được gửi tới server để lấy thêm bài viết và sau đó thêm chúng vào trang mà không tải lại trang.

Nạp bài viết khi cuộn trang

Chúng ta có thể bắt sự kiện scroll để tự động tải thêm bài viết khi người dùng cuộn đến gần cuối trang.

// Bắt sự kiện scroll
window.addEventListener('scroll', function() {
    if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
        loadMorePosts();
    }
});

// Hàm gửi yêu cầu AJAX để nạp thêm bài viết
function loadMorePosts() {
    const loadMoreButton = document.getElementById('loadMoreButton');
    loadMoreButton.disabled = true;  // Vô hiệu hóa nút khi đang tải
    loadMoreButton.innerHTML = "Đang tải...";

    // Gửi yêu cầu AJAX tới server
    fetch('loadMorePosts.php')
        .then(response => response.json())
        .then(data => {
            if (data.length > 0) {
                const postsContainer = document.getElementById('postsContainer');
                data.forEach(post => {
                    // Tạo bài viết mới và thêm vào DOM
                    const postDiv = document.createElement('div');
                    postDiv.classList.add('post');
                    postDiv.innerHTML = `
                        <h3>${post.title}</h3>
                        <p>${post.content}</p>
                    `;
                    postsContainer.appendChild(postDiv);
                });
            } else {
                loadMoreButton.innerHTML = "Không còn bài viết nào nữa";
            }
        })
        .catch(error => {
            console.error('Lỗi:', error);
            loadMoreButton.innerHTML = "Có lỗi xảy ra";
        })
        .finally(() => {
            loadMoreButton.disabled = false;  // Kích hoạt lại nút
        });
}

Xử lý yêu cầu khi nhấn nút "Tải thêm"

Nếu bạn muốn sử dụng nút "Tải thêm" thay vì tự động tải khi cuộn trang, bạn chỉ cần thêm một sự kiện click vào nút này.

document.getElementById('loadMoreButton').addEventListener('click', function() {
    loadMorePosts();
});

PHP: Xử lý và trả về dữ liệu bài viết

Chúng ta cần một file PHP (loadMorePosts.php) để xử lý yêu cầu AJAX và trả về danh sách các bài viết.

PHP (loadMorePosts.php):

<?php
header('Content-Type: application/json');

// Kết nối cơ sở dữ liệu (thay đổi thông tin kết nối cho phù hợp)
$conn = new mysqli('localhost', 'root', '', 'your_database');

// Kiểm tra kết nối
if ($conn->connect_error) {
    die("Kết nối thất bại: " . $conn->connect_error);
}

// Truy vấn cơ sở dữ liệu để lấy danh sách bài viết
$sql = "SELECT title, content FROM posts LIMIT 5";  // Giới hạn 5 bài viết mỗi lần tải thêm
$result = $conn->query($sql);

$posts = [];

if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        $posts[] = $row;
    }
}

// Trả về kết quả dưới dạng JSON
echo json_encode($posts);

// Đóng kết nối
$conn->close();
?>

Giải thích mã PHP:

  • $_GET['page']: Mặc dù trong ví dụ này chúng ta chưa sử dụng phân trang, nhưng trong trường hợp thực tế, bạn có thể sử dụng tham số page để truy vấn thêm dữ liệu theo trang.

  • Truy vấn cơ sở dữ liệu: Sử dụng SQL để lấy 5 bài viết mỗi lần. Bạn có thể thay đổi điều kiện hoặc số lượng bài viết tùy vào yêu cầu của ứng dụng.

  • Trả về dữ liệu dưới dạng JSON: Sau khi truy vấn xong, dữ liệu được trả về dưới dạng mảng JSON để JavaScript có thể xử lý.

Khi JavaScript nhận được dữ liệu bài viết từ server, các bài viết mới sẽ được thêm vào trang mà không làm mất các bài viết cũ. Các bài viết mới sẽ được hiển thị ngay dưới các bài viết đã tải trước đó.

Kết quả và cải tiến

  • Tải thêm tự động: Chức năng này giúp người dùng không cần phải nhấn nút "Tải thêm", mà thay vào đó chỉ cần cuộn xuống cuối trang để nạp thêm bài viết.

  • Nút "Tải thêm": Nút "Tải thêm" cung cấp một sự lựa chọn chủ động cho người dùng nếu họ không muốn sử dụng tính năng tự động tải.

Hiển thị dữ liệu thời gian thực trong JavaScript

Trong các ứng dụng web hiện đại, việc hiển thị dữ liệu thời gian thực như số liệu bán hàng, bảng thống kê, trạng thái đơn hàng là rất quan trọng. Các tính năng này cho phép người dùng thấy được sự thay đổi và cập nhật dữ liệu ngay lập tức mà không cần phải làm mới lại trang.

Chúng ta có thể sử dụng AJAX kết hợp với setInterval() hoặc WebSocket (đối với ứng dụng nâng cao) để cập nhật dữ liệu từ server và hiển thị ngay lập tức trên giao diện người dùng.

Sử dụng setInterval() để gửi yêu cầu định kỳ

setInterval() là một phương thức trong JavaScript giúp thực hiện một hành động nào đó theo một khoảng thời gian định kỳ. Ở đây, chúng ta sẽ sử dụng setInterval() để gửi yêu cầu AJAX tới server và nhận dữ liệu cập nhật từ server.

HTML: Giao diện hiển thị dữ liệu

Chúng ta cần một giao diện cơ bản để hiển thị các số liệu bán hàng hoặc trạng thái đơn hàng.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Thống kê thời gian thực</title>
    <style>
        #salesStats {
            font-size: 18px;
            margin-top: 20px;
        }
        #ordersStatus {
            font-size: 18px;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h2>Thống kê bán hàng</h2>
    <div id="salesStats">
        <p>Số lượng bán hàng: <span id="totalSales">0</span></p>
        <p>Doanh thu: <span id="totalRevenue">0</span></p>
    </div>

    <h2>Trạng thái đơn hàng</h2>
    <div id="ordersStatus">
        <p>Số đơn hàng đang xử lý: <span id="processingOrders">0</span></p>
        <p>Số đơn hàng đã hoàn thành: <span id="completedOrders">0</span></p>
    </div>

    <script src="app.js"></script>
</body>
</html>

Trong ví dụ này, chúng ta có 2 khu vực hiển thị thông tin: Số liệu bán hàngTrạng thái đơn hàng.

JavaScript: Sử dụng setInterval() để gửi yêu cầu AJAX định kỳ

Chúng ta sẽ sử dụng setInterval() để gửi yêu cầu AJAX đến server mỗi 5 giây (hoặc thời gian khác tùy theo yêu cầu) để lấy dữ liệu cập nhật.

// Hàm gửi yêu cầu AJAX để lấy dữ liệu từ server
function fetchRealTimeData() {
    // Gửi yêu cầu AJAX để lấy số liệu mới
    fetch('getSalesData.php')
        .then(response => response.json())
        .then(data => {
            // Cập nhật số liệu bán hàng và trạng thái đơn hàng
            document.getElementById('totalSales').textContent = data.totalSales;
            document.getElementById('totalRevenue').textContent = data.totalRevenue;
            document.getElementById('processingOrders').textContent = data.processingOrders;
            document.getElementById('completedOrders').textContent = data.completedOrders;
        })
        .catch(error => console.error('Lỗi khi lấy dữ liệu:', error));
}

// Gọi hàm fetchRealTimeData mỗi 5 giây
setInterval(fetchRealTimeData, 5000);

Giải thích mã JavaScript:

  • fetchRealTimeData: Hàm này gửi yêu cầu tới getSalesData.php để lấy số liệu bán hàng và trạng thái đơn hàng. Sau khi nhận được phản hồi, hàm sẽ cập nhật các phần tử HTML tương ứng với số liệu mới.

  • setInterval(fetchRealTimeData, 5000): Phương thức setInterval sẽ gọi hàm fetchRealTimeData mỗi 5 giây, đảm bảo dữ liệu luôn được cập nhật định kỳ.

PHP: Xử lý yêu cầu và trả về dữ liệu

Chúng ta cần một file PHP (getSalesData.php) để xử lý yêu cầu và trả về dữ liệu thời gian thực dưới dạng JSON.

PHP (getSalesData.php):

<?php
header('Content-Type: application/json');

// Kết nối cơ sở dữ liệu (thay đổi thông tin kết nối cho phù hợp)
$conn = new mysqli('localhost', 'root', '', 'your_database');

// Kiểm tra kết nối
if ($conn->connect_error) {
    die("Kết nối thất bại: " . $conn->connect_error);
}

// Truy vấn cơ sở dữ liệu để lấy số liệu bán hàng và trạng thái đơn hàng
$sqlSales = "SELECT COUNT(*) AS totalSales, SUM(amount) AS totalRevenue FROM sales WHERE date >= CURDATE()";  // Tổng số bán hàng hôm nay
$sqlOrders = "SELECT COUNT(*) AS processingOrders FROM orders WHERE status = 'Processing'";
$sqlCompleted = "SELECT COUNT(*) AS completedOrders FROM orders WHERE status = 'Completed'";

$resultSales = $conn->query($sqlSales);
$resultOrders = $conn->query($sqlOrders);
$resultCompleted = $conn->query($sqlCompleted);

$data = [
    'totalSales' => $resultSales->fetch_assoc()['totalSales'],
    'totalRevenue' => $resultSales->fetch_assoc()['totalRevenue'],
    'processingOrders' => $resultOrders->fetch_assoc()['processingOrders'],
    'completedOrders' => $resultCompleted->fetch_assoc()['completedOrders']
];

// Trả về dữ liệu dưới dạng JSON
echo json_encode($data);

// Đóng kết nối
$conn->close();
?>

Giải thích mã PHP:

  • Truy vấn cơ sở dữ liệu: Chúng ta truy vấn cơ sở dữ liệu để lấy tổng số bán hàng trong ngày (totalSales), doanh thu (totalRevenue), số đơn hàng đang xử lý (processingOrders) và số đơn hàng đã hoàn thành (completedOrders).

  • Trả về dữ liệu dưới dạng JSON: Dữ liệu được trả về dưới dạng JSON để JavaScript có thể dễ dàng xử lý và cập nhật giao diện.

Kết quả

Khi trang web được tải lên, dữ liệu sẽ được cập nhật liên tục mỗi 5 giây mà không cần phải tải lại trang. Điều này giúp người dùng luôn nhận được thông tin mới nhất về số liệu bán hàng và trạng thái đơn hàng mà không bị gián đoạn.

Cải tiến với WebSocket (nâng cao)

Sử dụng WebSocket là một phương pháp nâng cao để truyền tải dữ liệu thời gian thực mà không cần gửi yêu cầu liên tục từ client đến server. WebSocket tạo ra một kết nối liên tục giữa client và server, cho phép server gửi dữ liệu bất cứ khi nào có thay đổi mà không cần client phải gửi yêu cầu lại.

// Mở kết nối WebSocket với server
const socket = new WebSocket('ws://your-server.com/');

socket.onmessage = function(event) {
    const data = JSON.parse(event.data);
    document.getElementById('totalSales').textContent = data.totalSales;
    document.getElementById('totalRevenue').textContent = data.totalRevenue;
    document.getElementById('processingOrders').textContent = data.processingOrders;
    document.getElementById('completedOrders').textContent = data.completedOrders;
};

Kết bài

Việc sử dụng AJAX để thực hiện các tác vụ như lọc và phân trang động trong các trang web hiện đại không chỉ giúp cải thiện trải nghiệm người dùng mà còn tối ưu hóa hiệu suất và giảm tải cho server. Nhờ vào khả năng gửi yêu cầu và nhận phản hồi từ server mà không cần tải lại trang, AJAX đã trở thành một công cụ không thể thiếu trong phát triển ứng dụng web.

Các ví dụ thực tế như bộ lọc sản phẩm, tìm kiếm tự động, và nạp dữ liệu theo yêu cầu đều minh họa cách thức AJAX giúp xây dựng các trang web tương tác, nhanh chóng và mượt mà. Tuy nhiên, khi sử dụng AJAX, chúng ta cần lưu ý đến việc xử lý lỗi, bảo mật dữ liệu, và tối ưu hiệu suất để đảm bảo ứng dụng hoạt động ổn định và an toàn.

Tóm lại, việc hiểu và ứng dụng AJAX đúng cách trong các tình huống thực tế không chỉ giúp nâng cao trải nghiệm người dùng mà còn góp phần quan trọng trong việc xây dựng các ứng dụng web hiện đại, nhanh chóng và hiệu quả.

Bài viết liên quan