Создание интерактивных квизов — один из популярных способов вовлечь посетителей сайта. Однако при большом количестве вопросов классические квизы могут замедлять загрузку страницы, особенно если все вопросы загружаются сразу. В этой статье разберём, как сделать динамический квиз с подгрузкой вопросов по одному через AJAX в WordPress.
Зачем нужен динамический квиз с подгрузкой вопросов
Если загружать все вопросы сразу при открытии страницы, это может привести к:
- Увеличению времени загрузки страницы;
- Потере интереса пользователя из-за долгой загрузки;
- Проблемам с мобильными устройствами и медленным интернетом;
- Большей нагрузке на сервер.
Динамическая подгрузка позволяет загружать только один вопрос за раз после ответа на предыдущий, что значительно улучшает UX и уменьшает нагрузку.
Основные принципы работы квиза с подгрузкой вопросов
Сценарий работы:
- Пользователь открывает страницу с квизом — загружается только первый вопрос;
- После выбора ответа отправляется AJAX-запрос на сервер для получения следующего вопроса;
- Вопросы отображаются по очереди, пока не закончится список;
- В конце показывается результат или сообщение.
Создание кастомного плагина для динамического квиза
Создадим простой плагин, который реализует такой квиз. Для примера вопросы будут храниться в PHP-массиве, но можно легко адаптировать для хранения в базе данных.
Шаг 1. Создаём структуру плагина
В каталоге wp-content/plugins создайте папку wpquiz-dynamic, внутри файл wpquiz-dynamic.php с заголовком плагина:
<?php
/*
Plugin Name: WPQuiz Dynamic Loader
Description: Динамический квиз с подгрузкой вопросов через AJAX
Version: 1.0
Author: WPQuiz.ru
*/
Шаг 2. Добавляем массив с вопросами
function wpquiz_dynamic_get_questions() {
return [
1 => [
'question' => 'Какой язык программирования используется для разработки WordPress?',
'answers' => [
'Python',
'JavaScript',
'PHP',
'Ruby',
],
'correct' => 2 // индекс правильного ответа (0-based)
],
2 => [
'question' => 'Какой хук используется для инициализации плагинов в WordPress?',
'answers' => [
'init',
'wp_head',
'admin_init',
'wp_footer',
],
'correct' => 0
],
3 => [
'question' => 'Какой файл отвечает за шаблон главной страницы в теме WordPress?',
'answers' => [
'index.php',
'home.php',
'front-page.php',
'single.php',
],
'correct' => 2
],
];
}Шаг 3. Регистрируем шорткод для вывода квиза
function wpquiz_dynamic_shortcode() {
ob_start();
?>
<div id="wpquiz-dynamic-container">
<div id="wpquiz-question">Загрузка вопроса...</div>
<div id="wpquiz-answers"></div>
</div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
let currentQuestion = 1;
function loadQuestion(id) {
fetch(wpquiz_dynamic_ajax_object.ajax_url, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=wpquiz_dynamic_load_question&question_id=' + id
})
.then(response => response.json())
.then(data => {
if(data.success) {
document.getElementById('wpquiz-question').innerText = data.data.question;
const answersDiv = document.getElementById('wpquiz-answers');
answersDiv.innerHTML = '';
data.data.answers.forEach((answer, index) => {
const btn = document.createElement('button');
btn.innerText = answer;
btn.addEventListener('click', () => {
if(index === data.data.correct) {
alert('Правильный ответ!');
} else {
alert('Неправильно. Попробуйте следующий вопрос.');
}
currentQuestion++;
if(currentQuestion <= data.data.total) {
loadQuestion(currentQuestion);
} else {
document.getElementById('wpquiz-question').innerText = 'Квиз завершён! Спасибо за участие.';
document.getElementById('wpquiz-answers').innerHTML = '';
}
});
answersDiv.appendChild(btn);
});
} else {
document.getElementById('wpquiz-question').innerText = 'Вопрос не найден.';
document.getElementById('wpquiz-answers').innerHTML = '';
}
});
}
loadQuestion(currentQuestion);
});
</script>
<?php
return ob_get_clean();
}
add_shortcode('wpquiz_dynamic', 'wpquiz_dynamic_shortcode');Шаг 4. Обработка AJAX-запроса
function wpquiz_dynamic_load_question() {
$question_id = isset($_POST['question_id']) ? intval($_POST['question_id']) : 1;
$questions = wpquiz_dynamic_get_questions();
if(isset($questions[$question_id])) {
wp_send_json_success([
'question' => $questions[$question_id]['question'],
'answers' => $questions[$question_id]['answers'],
'correct' => $questions[$question_id]['correct'],
'total' => count($questions),
]);
} else {
wp_send_json_error('Вопрос не найден');
}
}
add_action('wp_ajax_wpquiz_dynamic_load_question', 'wpquiz_dynamic_load_question');
add_action('wp_ajax_nopriv_wpquiz_dynamic_load_question', 'wpquiz_dynamic_load_question');Шаг 5. Локализация скрипта
function wpquiz_dynamic_enqueue_scripts() {
wp_enqueue_script('wpquiz-dynamic-script', plugin_dir_url(__FILE__) . 'dummy.js', [], false, true);
wp_localize_script('wpquiz-dynamic-script', 'wpquiz_dynamic_ajax_object', [
'ajax_url' => admin_url('admin-ajax.php')
]);
}
add_action('wp_enqueue_scripts', 'wpquiz_dynamic_enqueue_scripts');Для простоты примера, JS код вставлен прямо в шорткод. В реальном проекте лучше вынести в отдельный файл и подключать через wp_enqueue_script.
Дополнительные советы по улучшению динамического квиза
Кэширование и оптимизация
При большом количестве вопросов лучше хранить их в базе данных с индексами. Для ускорения можно использовать объектный кэш или transient API. Если вопросы статичны, кэшируйте ответы AJAX-запроса на стороне клиента.
Расширение функционала
Можно добавить:
- Подсчёт баллов и вывод результатов;
- Варианты с несколькими правильными ответами;
- Временной лимит на ответ;
- Анимации и улучшенный интерфейс с React или Vue.js.
Использование готовых решений
Если хочется использовать готовые плагины с поддержкой динамических квизов, обратите внимание на Quizle от WPShop — мощный и гибкий инструмент с поддержкой AJAX и множеством настроек.
Вывод
Динамический квиз с подгрузкой вопросов — отличный способ улучшить взаимодействие с пользователями и повысить производительность сайта. Реализовать его можно самостоятельно с помощью AJAX и PHP, как показано в примере, или использовать готовые решения, например, Quizle от WPShop.