Đếm lượt đọc bài chính xác (dựa theo phần trăm đọc + thời gian ở lại)

Nếu bạn đang muốn đếm lượt đọc bài viết một cách chính xác hơn so với cách đếm mỗi lần load trang, thì cần dựa vào hành vi thực tế của người đọc như phần trăm nội dung đã cuộn qua và thời gian ở lại trang. Bài viết này hướng dẫn cách kết hợp JavaScript với REST API để làm điều đó.

Đếm lượt đọc bài chính xác (dựa theo phần trăm đọc + thời gian ở lại)

Vì sao không nên dùng page view thông thường?

Phương pháp Vấn đề
Đếm mỗi lần truy cập Tính cả bot, reload, thoát nhanh → sai lệch rất nhiều.
Đếm lượt cuộn qua đoạn giữa Không kiểm soát được thời gian thực sự đọc.

Mục tiêu

  • Chỉ tính 1 lượt đọc nếu người dùng ở lại ít nhất X giây
  • Và đã cuộn qua ít nhất Y% độ dài bài viết

Ý tưởng kỹ thuật

  • Gắn listener scroll và timer
  • Khi đã scroll qua ≥ 75% nội dung và ở lại ≥ 15 giây, gọi API đếm 1 view
  • Dùng cookie hoặc sessionStorage để không đếm lặp nhiều lần

Đoạn code thêm vào footer.php

<?php if (is_single()) : ?>
    <script>window.post_id = <?= get_the_ID(); ?>;</script>
<?php endif; ?>

Đoạn code JavaScript mẫu

(function () {
    if (!window.post_id) return;

    const key = `viewed_${window.post_id}`;
    if (sessionStorage.getItem(key)) return;

    let scrollPassed = false;
    let timePassed = false;
    let alreadySent = false;

    // Sau 15 giây
    setTimeout(() => {
        timePassed = true;
        triggerCount();
    }, 15000);

    // Scroll vượt 75%
    window.addEventListener("scroll", () => {
        const docHeight = document.documentElement.scrollHeight - window.innerHeight;
        const scrolled = window.scrollY;
        if ((scrolled / docHeight) > 0.75) {
            scrollPassed = true;
            triggerCount();
        }
    });

    function triggerCount() {
        if (scrollPassed && timePassed && !alreadySent) {
            alreadySent = true; // đảm bảo không gửi nhiều lần
            fetch('/wp-json/custom/v1/count-read', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ post_id: window.post_id })
            }).then(() => {
                sessionStorage.setItem(key, "1");
            });
        }
    }
})();

Tạo endpoint REST API để xử lý

add_action('rest_api_init', function () {
  register_rest_route('custom/v1', '/count-read', [
    'methods' => 'POST',
    'callback' => 'custom_count_post_read',
    'permission_callback' => '__return_true'
  ]);
});

function custom_count_post_read($request) {
  $post_id = absint($request->get_param('post_id'));
  if ($post_id) {
    $views = (int) get_post_meta($post_id, '_true_read_count', true);
    update_post_meta($post_id, '_true_read_count', $views + 1);
    return rest_ensure_response(['status' => 'ok']);
  }
  return new WP_Error('invalid', 'No post ID', ['status' => 400]);
}

Hiển thị lượt đọc thực tế

<?php
$read = (int) get_post_meta(get_the_ID(), '_true_read_count', true);
echo "Bài viết đã được đọc thật sự: " . number_format($read) . " lượt.";
?>

Không phải lượt view nào cũng là một lượt đọc thật sự. Hãy chọn cách đếm thông minh để biết bài viết nào thực sự có giá trị với độc giả!

Gợi ý nâng cao

  • Tùy chỉnh tỷ lệ scroll (%), thời gian ở lại tuỳ theo độ dài bài viết
  • Gắn thêm check nếu user tương tác (bấm nút, copy đoạn…) để tăng độ chính xác
  • Lưu IP hash để chống spam
  • Hiển thị biểu đồ heatmap đọc bài nếu muốn phân tích sâu

Với giải pháp trên, bạn không chỉ biết bài viết nào được click, mà còn thực sự được đọc và quan tâm. Đó mới là giá trị thật sự.

Bình Luận


  • Không có bình luận.