Вопрос или проблема
Я пытаюсь динамически загрузить Reveal.js внутри базового маршрутизатора SPA на чистом JS, но у меня просто не получается запустить Reveal.js. Фон отображается, значит, он распознается, и файлы загружаются. Однако слайды просто не отображаются правильно. Я не могу найти решение ни с помощью Google, ни LLM, ни чем-то подобным. Может кто-то помочь мне, прежде чем я совсем сойду с ума 🙂
index.html
main.js
|- views
| |- index.html
| |- index.js
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title></title>
</head>
<body>
<div id="app"></div>
<script src="main.js" type="module"></script>
</body>
</html>
main.js
const route = (event) => {
event = event || window.event;
event.preventDefault();
window.history.pushState({}, '', event.target.href);
handleLocation();
};
const routes = {
"https://stackoverflow.com/": { title: 'Главная', path: '/views/index.html', script: '/views/index.js' },
'404': { title: '404', path: '/views/404.html' },
};
const handleLocation = async () => {
const path = window.location.pathname;
const route = routes[path]?.path || routes['404'].path;
const html = await fetch(route).then((data) => data.text());
document.querySelector('#app').innerHTML = html;
// Загружаем скрипты
if (routes[path]?.script) {
const script = document.createElement('script');
script.type="module";
script.src = routes[path].script;
document.body.appendChild(script);
}
};
window.onpopstate = handleLocation;
window.route = route;
handleLocation();
views/index.html
<div class="reveal">
<div class="slides">
<section>
<h1>Ладида</h1>
</section>
</div>
</div>
views/index.js
import 'reveal.js/dist/reset.css';
import 'reveal.js/dist/reveal.css';
import 'reveal.js/dist/theme/black.css';
import Reveal from 'reveal.js';
import Highlight from 'reveal.js/plugin/highlight/highlight.esm.js';
(async () => {
requestAnimationFrame(() => {
Reveal.initialize({
plugins: [Highlight],
slideNumber: 'c/t',
showSlideNumber: 'all',
});
});
})();
Ответ или решение
Решение проблемы с загрузкой Reveal.js в динамической SPA
При интеграции библиотеки Reveal.js в динамическое одностраничное приложение (SPA), построенное на чистом JavaScript, могут возникать различные проблемы, мешающие корректной загрузке слайдов. Рассмотрим все возможные причины и пути их решения.
1. Структура проекта
Ваш проект выглядит следующим образом:
index.html
main.js
|- views
| |- index.html
| |- index.js
Мы видим, что основная логика маршрутизации сосредоточена в main.js
, а слайды реализованы в views/index.html
и их поведение управляется через views/index.js
.
2. Проверьте порядок загрузки скриптов
Одной из распространённых причин проблем с Reveal.js является неправильный порядок загрузки JavaScript-файлов. Reveal.js требует, чтобы DOM был полностью загружен перед инициализацией. Убедитесь, что вы инициализируете Reveal.js только после полной загрузки HTML-содержимого:
const handleLocation = async () => {
const path = window.location.pathname;
const route = routes[path]?.path || routes['404'].path;
const html = await fetch(route).then((data) => data.text());
document.querySelector('#app').innerHTML = html;
// Загрузка и выполнение скрипта
if (routes[path]?.script) {
const script = document.createElement('script');
script.type = "module";
script.src = routes[path].script;
script.onload = () => {
// Инициализация Reveal.js должна происходить здесь
Reveal.initialize({
plugins: [Highlight],
slideNumber: 'c/t',
showSlideNumber: 'all',
});
};
document.body.appendChild(script);
}
};
3. Обработка событий и асинхронность
Использование requestAnimationFrame
может вызвать проблемы, если в момент вызова Reveal.initialize
DOM-элементы, относящиеся к слайдам, ещё не полностью готовы. Вместо этого вызывайте инициализацию сразу после добавления скрипта, как показано выше.
4. Убедитесь, что стили загружены корректно
Неправильная загрузка CSS-файлов также может повлиять на внешний вид и работу слайдов. Проверьте, загружаются ли стили Reveal.js. Вы можете включить их непосредственно в главный HTML-файл или импортировать через JavaScript:
import 'reveal.js/dist/reset.css';
import 'reveal.js/dist/reveal.css';
import 'reveal.js/dist/theme/black.css';
5. Проверьте пути к ресурсам
Проверьте правильность путей к файлам в main.js
и index.js
. Убедитесь, что файлы доступны по указанным URL. Вы можете использовать инструменты разработчика (F12), чтобы отследить ошибки загрузки в консоли.
6. Дебаг и отладка
Используйте консольные сообщения для отладки. Добавьте console.log
в ключевых участках кода, чтобы убедиться, что выполнение доходит до вызова Reveal.initialize
и что все необходимые элементы присутствуют на странице.
console.log('Initializing Reveal with slides:', document.querySelector('.reveal'));
Заключение
Следуя вышеизложенным рекомендациям, вы сможете устранить проблемы с загрузкой Reveal.js в вашем динамическом SPA. Обязательно проверьте порядок загрузки скриптов, убедитесь в корректной доступности файлов, и не забывайте использовать инструменты разработки для отладки. Удачи в вашем проекте!