Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как динамически подгружать js-код для SPA? (https://javascript.ru/forum/misc/82365-kak-dinamicheski-podgruzhat-js-kod-dlya-spa.html)

AlexLF 23.04.2021 18:34

Как динамически подгружать js-код для SPA?
 
Я пробую делать spa-сайт с помощью обычного JavaScript. Выглядит это примерно так:

Есть центральный пустой блок:

<div id="main"></div>

и есть десяток кнопок в меню. Когда кликаешь на кнопку, должно подгружаться содержимое центрального блока. Соответственно, есть десяток html-файлов, где хранится содержимое состояний центрального блока.

Подгружаю html код из этих файликов с помощью фетча и вставляю его в центральный блок. Примерно так:

let elem = document.getElementById('main')
export async function fetchHTML(address, elem) {
	return fetch(address) 
		.then(
			response => {
				return response.text();
			},
			error => {
				console.log('Ошибка фетча', error)
			})
		.then((response) => {
			elem.innerHTML = response;
		})
}

Все работает, кликаю на кнопки, содержимое файлов загружается в центральный див. Красота, это и есть SPA.

Засада заключается в том, что код, вставляемый с помощью innerHTML, не работает. В html-файлах может быть сколько угодно <script>, все они совершенно инертны. При этом, в каждом файле может быть js-код, который обслуживает именно этот файл. Например, делает что-то с местными дивами, имеющими определенный id.

Такое поведение innerHTML неприятно. Было бы хорошо и логично сразу держать в одном файле и html, и js. Можно было бы даже делать отладку одного файла.

Однако, хотелось бы динамически подгружать и js-код, т.к. это и подразумевается в "рекламных" статьях про SPA. Подгрузка только статического HTML неинтересна.

Рядом с каждым html-файлом я насоздавал по js-файлу, который обслуживает этот html-файл. Как его запустить? Если простые листенеры на клик, которые обслуживают класс элементов, то проблем нет, достаточно запустить import(jsAddress).

А запустить код, который должен обработать html-код в момент запуска, например, обслужить конкретный id, какие-то элементы создать, и что-то там собрать - не получается.


Я пробовал так, например:
import(jsAddress)
	.then((module) => module.run())

Нужно, чтобы js-код запускался каждый раз, когда подгружается html-код. А не только первый раз, когда загружается модуль.

В общем, пока получается не SPA, как его рисуют, а бесполезная загружалка html.

Я начинаю использовать Vue. Там та жа история - бесполезно что-то вставлять в html-код, который будет в центральном диве. Vue его не сможет обслужить. И если нужно обслужить конкретный элемент, с конкретным id, пока его нет в центральном диве, экземпляр Vue для него не создать, будет выдавать ошибку, что нет такого id.

(Сборщиками кода пока не пользовался - и не очень понимаю пока, зачем они. Хотя может быть в них и находится ответ. Но по идее, это должно как-то в обычном JavaScript решаться.)

рони 23.04.2021 18:46

AlexLF,
https://javascript.ru/forum/misc/791...ri-nego-2.html

voraa 23.04.2021 19:30

Для подобных вещей есть обычная штука - iframe.

ksa 23.04.2021 20:32

Цитата:

Сообщение от AlexLF
это и есть SPA

Скорее пародия на СПА... ;)

AlexLF 23.04.2021 23:58

Цитата:

Сообщение от voraa (Сообщение 535864)
Для подобных вещей есть обычная штука - iframe.

Я попробовал - и html загружается, и js выполняется. Столько раз сколько надо. (Что ожидаемо.)

Проблема, что данные из модуля в модуль по-человечески не передаются - с помощью import {...} :-? По крайней мере, пока не получилось.

Можно попробовать передавать данные с postMessage, но postMessage + import это как-то...

iframe внутри собственного сайта - выглядит экзотично. Неужели во взрослых фреймворках такими же приемами пользуются? - не верится.

AlexLF 23.04.2021 23:59

Цитата:

Сообщение от ksa (Сообщение 535865)
Скорее пародия на СПА... ;)

Что не так? Как надо?

Aetae 24.04.2021 00:02

Цитата:

Сообщение от AlexLF (Сообщение 535868)
Что не так? Как надо?

Надо юзать заточенные под это дело либы\фреймворки, в которых умные люди за десяток-другой лет существования концепции разобрались со всеми возможными проблемами и задачами, а не изобретать велосипед.)

Rise 24.04.2021 03:36

Цитата:

Сообщение от AlexLF
данные из модуля в модуль по-человечески не передаются

А зачем модули использовать, никто же не заставляет?

voraa 24.04.2021 06:59

Цитата:

Сообщение от AlexLF
В общем, пока получается не SPA, как его рисуют, а бесполезная загружалка html.

Цитата:

Сообщение от AlexLF
Что не так? Как надо?

Это именно и есть не SPA, а загружалка html. Какая то имитация iframe.
SPA не грузит постоянно html код с сервера. С сервера должны загружаться данные. А на основании этих данных приложение формирует страницу. Если, что и подгружается, то это файлы js, css, в том случае, если они нужны, для блоков, которые используются редко.

ksa 24.04.2021 08:55

voraa, если страница не перезагружается - это уже некая модель СПА... :D
Другое дело ее реализация.

Цитата:

Сообщение от AlexLF
Как надо?

Почитай про ReactJS или VueJS - тогда поймешь разницу. ;)


Часовой пояс GMT +3, время: 20:53.