Reveal.js не загружается в динамическом загрузчике представлений SPA.

Вопрос или проблема

Я пытаюсь динамически загрузить 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. Обязательно проверьте порядок загрузки скриптов, убедитесь в корректной доступности файлов, и не забывайте использовать инструменты разработки для отладки. Удачи в вашем проекте!

Оцените материал
Добавить комментарий

Капча загружается...