Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #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 решаться.)
Ответить с цитированием
  #2 (permalink)  
Старый 23.04.2021, 18:46
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,135

AlexLF,
https://javascript.ru/forum/misc/791...ri-nego-2.html
Ответить с цитированием
  #3 (permalink)  
Старый 23.04.2021, 19:30
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,756

Для подобных вещей есть обычная штука - iframe.
Ответить с цитированием
  #4 (permalink)  
Старый 23.04.2021, 20:32
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,236

Сообщение от AlexLF
это и есть SPA
Скорее пародия на СПА...
Ответить с цитированием
  #5 (permalink)  
Старый 23.04.2021, 23:58
Интересующийся
Отправить личное сообщение для AlexLF Посмотреть профиль Найти все сообщения от AlexLF
 
Регистрация: 26.09.2012
Сообщений: 14

Сообщение от voraa Посмотреть сообщение
Для подобных вещей есть обычная штука - iframe.
Я попробовал - и html загружается, и js выполняется. Столько раз сколько надо. (Что ожидаемо.)

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

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

iframe внутри собственного сайта - выглядит экзотично. Неужели во взрослых фреймворках такими же приемами пользуются? - не верится.
Ответить с цитированием
  #6 (permalink)  
Старый 23.04.2021, 23:59
Интересующийся
Отправить личное сообщение для AlexLF Посмотреть профиль Найти все сообщения от AlexLF
 
Регистрация: 26.09.2012
Сообщений: 14

Сообщение от ksa Посмотреть сообщение
Скорее пародия на СПА...
Что не так? Как надо?
Ответить с цитированием
  #7 (permalink)  
Старый 24.04.2021, 00:02
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,590

Сообщение от AlexLF Посмотреть сообщение
Что не так? Как надо?
Надо юзать заточенные под это дело либы\фреймворки, в которых умные люди за десяток-другой лет существования концепции разобрались со всеми возможными проблемами и задачами, а не изобретать велосипед.)
__________________
29375, 35
Ответить с цитированием
  #8 (permalink)  
Старый 24.04.2021, 06:59
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,756

Сообщение от AlexLF
В общем, пока получается не SPA, как его рисуют, а бесполезная загружалка html.
Сообщение от AlexLF
Что не так? Как надо?
Это именно и есть не SPA, а загружалка html. Какая то имитация iframe.
SPA не грузит постоянно html код с сервера. С сервера должны загружаться данные. А на основании этих данных приложение формирует страницу. Если, что и подгружается, то это файлы js, css, в том случае, если они нужны, для блоков, которые используются редко.
Ответить с цитированием
  #9 (permalink)  
Старый 24.04.2021, 08:55
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,236

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

Сообщение от AlexLF
Как надо?
Почитай про ReactJS или VueJS - тогда поймешь разницу.
Ответить с цитированием
  #10 (permalink)  
Старый 24.04.2021, 14:21
Интересующийся
Отправить личное сообщение для AlexLF Посмотреть профиль Найти все сообщения от AlexLF
 
Регистрация: 26.09.2012
Сообщений: 14

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

У меня стояла задача менять состояния центрального блока main. Для этого - раньше - я складывал в main дивы со всеми возможными состояниями. И делал видимым только один див, который должен быть активным на этот момент. Не знаю, делают ли так, но это вполне работало.

Меня не устраивало, как собираются все дивы в центральном блоке. Не делать же один большой див. Я разбивал на разные php-файлы, отвечающие разным состояниям, и собирал с помощью стопки функций include ''file_name.php" с помощью php. js-код в php-файлах работал без проблем.

Это работало, но приходилось следить в разных местах, чтобы файлы всех состояний были. В общем, некрасиво, и php я не люблю. Решил заменить на подгрузку с помощью фетча.

Но, пожалуй, вернусь к единоразовой загрузки дивов со всеми состояниями, и к загрузке всего js-кода. Пускай загружается, и так и лежит. Если загружать и уничтожать в innerHTML код - полагаю, мне это в будущем отзовется разными непредсказуемостями. Тот же Vue, полагаю, тоже отреагирует негативно, если после запуска "подгрузить еще немного" Vue-объектов.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не соображу как переписать код js в jquery Fomax Элементы интерфейса 1 12.10.2016 01:20
PopUp как выполнить код один раз для сессии kznsky Events/DOM/Window 5 03.03.2015 13:48
Как можно скопировать js код с другого сайта vuler Общие вопросы Javascript 1 17.02.2015 18:05
Как подгрузить код JS динамически? zhurchik Общие вопросы Javascript 22 02.02.2015 14:16
можно ли с помощью js написать код для симуляции нажатия на клавиш. KamalovRadik Мобильный JavaScript 7 17.02.2012 22:27