
Bạn muốn người dùng đọc bài viết đủ 30 giây hoặc một khoảng thời gian nhất định rồi mới hiển thị nội dung quan trọng. Điều này giúp tăng thời gian đọc bài viết, cải thiện tỷ lệ thoát trang (Bounce Rate) và tối ưu SEO. Trong bài viết này, hnitmedia.com sẽ hướng dẫn bạn cách code chức năng phải xem đủ thời gian để hiển thị nội dung trong wordpress này bằng shortcode trong WordPress.

Cách hoạt động của chức năng này
- Người dùng truy cập trang và phải cuộn trang để kích hoạt bộ đếm.
- Nếu bật yêu cầu đăng nhập, hệ thống chỉ đếm khi người dùng đã đăng nhập.
- Sau khi đủ thời gian quy định, nội dung sẽ hiển thị tự động kèm hiệu ứng mượt mà.
- Hiệu ứng thanh tiến trình giúp người dùng theo dõi thời gian chờ.
- Popup chúc mừng khi hoàn thành thời gian đọc bài.
Code chức năng xem đủ thời gian để hiển thị nội dung
Đặt đoạn code sau vào file functions.php để tạo shortcode
function hnitmedia_an_shortcode($atts, $content = null) {
$atts = shortcode_atts(array(
'login_required' => '0', // 0: Không yêu cầu đăng nhập, 1: Yêu cầu đăng nhập
), $atts, 'hnitmedia-an');
$login_required = intval($atts['login_required']);
$is_logged_in = is_user_logged_in();
if ($login_required === 1 && !$is_logged_in) {
return '<div class="hnitmedia-an-box">🚫 Bạn cần đăng nhập để xem nội dung này!</div>';
}
return '<div class="hnitmedia-an-box">
⏳ Nội dung sẽ xuất hiện sau <span id="hnitmedia-an-countdown">30</span> giây...
<div class="hnitmedia-an-progress-container">
<div id="hnitmedia-an-progress-bar" class="hnitmedia-an-progress-bar"></div>
</div>
</div>
<div id="hnitmedia-an-hidden-content" class="hnitmedia-an-hidden" style="display:none;">' . do_shortcode($content) . '</div>
<script>
let countdown = 30;
let countdownEl = document.getElementById("hnitmedia-an-countdown");
let progressBar = document.getElementById("hnitmedia-an-progress-bar");
let hiddenContent = document.getElementById("hnitmedia-an-hidden-content");
let timer = setInterval(() => {
countdown--;
countdownEl.innerText = countdown;
progressBar.style.width = ((30 - countdown) / 30) * 100 + "%";
if (countdown <= 0) {
clearInterval(timer);
hiddenContent.style.display = "block";
}
}, 1000);
</script>';
}
add_shortcode('hnitmedia-an', 'hnitmedia_an_shortcode');
Sử dụng shortcode trong bài viết
[hnitmedia-an login_required=”1″] nội dung muốn ẩn [/hnitmedia-an]- Nếu đặt
login_required="1"
, chỉ những người đã đăng nhập mới thấy nội dung sau 30 giây. - Nếu đặt
login_required="0"
, bất kỳ ai cũng có thể xem nội dung sau 30 giây.

Cải tiến nâng cao
- Thêm âm thanh thông báo khi hết thời gian.
- Chặn người dùng rời tab để tránh gian lận.
- Lưu thời gian đọc vào localStorage để không bị reset khi tải lại trang.
Code và css hoàn chỉnh của chức năng xem đủ thời gian để hiển thị nội dung
Bạn chỉ cần coppy toàn bộ file này, bỏ vào funtion.php là nó sẽ chạy thôi nhé, và hơn nữa là đẹp như của mình luôn nhé.
function hnitmedia_an_shortcode($atts, $content = null) {
$atts = shortcode_atts(array(
'login_required' => '0', // Mặc định không yêu cầu đăng nhập
), $atts, 'hnitmedia-an');
$login_required = intval($atts['login_required']);
$is_logged_in = is_user_logged_in();
// Nếu yêu cầu đăng nhập nhưng người dùng chưa đăng nhập, hiển thị thông báo
if ($login_required === 1 && !$is_logged_in) {
return '<div class="hnitmedia-an-box">🚫 Bạn cần đăng nhập để xem nội dung này!</div>';
}
return '<div class="hnitmedia-an-box">
⏳ Nội dung sẽ xuất hiện sau <span id="hnitmedia-an-countdown">30</span> giây...
<div class="hnitmedia-an-progress-container">
<div id="hnitmedia-an-progress-bar" class="hnitmedia-an-progress-bar"></div>
</div>
</div>
<div id="hnitmedia-an-hidden-content" class="hnitmedia-an-hidden" style="display:none;">' . do_shortcode($content) . '</div>
<div id="hnitmedia-an-popup" class="hnitmedia-an-popup">
🎊 Bạn đã hoàn thành 30 giây! 🎊
</div>
<script>
let loginRequired = ' . $login_required . ';
let isUserLoggedIn = ' . ($is_logged_in ? 'true' : 'false') . ';
</script>';
}
add_shortcode('hnitmedia-an', 'hnitmedia_an_shortcode');
function hnitmedia_an_script() {
if (!is_single()) return; ?>
<script>
document.addEventListener("DOMContentLoaded", function () {
if (loginRequired === 1 && !isUserLoggedIn) return;
let countdownEl = document.getElementById("hnitmedia-an-countdown");
let hiddenContent = document.getElementById("hnitmedia-an-hidden-content");
let progressBar = document.getElementById("hnitmedia-an-progress-bar");
let popup = document.getElementById("hnitmedia-an-popup");
let audio = new Audio("https://www.soundjay.com/button/beep-07.wav");
let hasScrolled = false;
let isTabActive = true;
window.addEventListener("scroll", function () { hasScrolled = true; });
document.addEventListener("visibilitychange", function () { isTabActive = !document.hidden; });
let startTime = localStorage.getItem("hnitmedia_an_time");
let currentTime = Math.floor(Date.now() / 1000);
let elapsed = startTime ? currentTime - parseInt(startTime) : 0;
let remainingTime = 30 - elapsed;
if (remainingTime < 0) remainingTime = 0;
function updateCountdown() {
if (!hasScrolled || !isTabActive) return;
countdownEl.innerText = remainingTime;
progressBar.style.width = ((30 - remainingTime) / 30) * 100 + "%";
if (remainingTime <= 0) {
hiddenContent.style.display = "block";
hiddenContent.classList.add("hnitmedia-an-fade-in");
progressBar.classList.add("hnitmedia-an-complete");
audio.play();
popup.style.display = "flex";
setTimeout(() => { popup.classList.add("hnitmedia-an-fadeout"); }, 3000);
clearInterval(timer);
localStorage.removeItem("hnitmedia_an_time");
}
remainingTime--;
}
if (!startTime || elapsed >= 30) {
localStorage.setItem("hnitmedia_an_time", currentTime);
remainingTime = 30;
}
let timer = setInterval(updateCountdown, 1000);
updateCountdown();
});
</script>
<style>
.hnitmedia-an-hidden {
display: none;
padding: 15px;
background: #f8f9fa;
border: 2px solid #ff9800;
margin-top: 20px;
font-size: 16px;
border-radius: 8px;
box-shadow: 0px 3px 15px rgba(255, 152, 0, 0.5);
opacity: 0;
transform: scale(0.8);
transition: opacity 1s ease-out, transform 0.8s ease-out;
}
.hnitmedia-an-hidden.hnitmedia-an-fade-in {
opacity: 1;
transform: scale(1);
}
.hnitmedia-an-box {
font-size: 18px;
font-weight: bold;
color: #ff5722;
margin-bottom: 15px;
text-align: center;
}
.hnitmedia-an-progress-container {
width: 100%;
height: 8px;
background: #ddd;
border-radius: 5px;
overflow: hidden;
margin-top: 10px;
position: relative;
}
.hnitmedia-an-progress-bar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, #ff5722, #ff9800);
transition: width 1s ease-out;
}
.hnitmedia-an-progress-bar.hnitmedia-an-complete {
background: linear-gradient(90deg, #4caf50, #8bc34a);
}
/* Popup chúc mừng */
.hnitmedia-an-popup {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.8);
padding: 20px;
border-radius: 10px;
text-align: center;
color: #fff;
font-size: 18px;
animation: muathemewpgiare-an-fadeIn 1s;
z-index: 999;
}
.hnitmedia-an-fadeout {
animation: hnitmedia-an-fadeOut 1s forwards;
}
@keyframes hnitmedia-an-fadeIn {
from { opacity: 0; transform: translate(-50%, -55%); }
to { opacity: 1; transform: translate(-50%, -50%); }
}
@keyframes hnitmedia-an-fadeOut {
from { opacity: 1; transform: translate(-50%, -50%); }
to { opacity: 0; transform: translate(-50%, -45%); }
}
</style>
<?php }
add_action('wp_footer', 'hnitmedia_an_script');