Показать сообщение отдельно
  #1 (permalink)  
Старый 23.04.2021, 18:34
Интересующийся
Отправить личное сообщение для AlexLF Посмотреть профиль Найти все сообщения от AlexLF
 
Регистрация: 26.09.2012
Сообщений: 14

Как динамически подгружать 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 решаться.)
Ответить с цитированием