Есть ли способ подключить в script1.js скрипт script2.js не используя document.write для вставки и defer для scipt3.js так, чтобы он выполнился до scipt3.js?
script1.js:
let script2 = document.createElement("script");
script2.src = "script2.js";
script2.async = false;
// Эти варианты не работают - script2.js выполняется после script3.js (пробовал в последнем Edge)
// document.head.appendChild(script2);
// document.head.insertBefore(script2, document.head.firstChild);
// С document.write работает, но этого хотелось бы избежать, к тому же он помечен как устаревший
// document.write('<script src="script2.js"></script>');
Re: Загрузка и выполнение скрипта2 из скрипта1 перед сриптом3
Здравствуйте, rFLY, Вы писали:
FLY>Есть ли способ подключить в script1.js скрипт script2.js не используя document.write для вставки и defer для scipt3.js так, чтобы он выполнился до scipt3.js?
Я в таких случаях теперь просто звоню Слоу спрашиваю Клода
Unfortunately, Claude is only available in certain regions right now.
PS: На счет ИИ. Когда я гуглил решение этого вопроса, мне в разделе "Обзор от ИИ" были предложены варианты, которые я уже пробовал и написал здесь (т.е. не рабочие). Но это уже тема для отдельного форума.
Re[3]: Загрузка и выполнение скрипта2 из скрипта1 перед сриптом3
FLY>Unfortunately, Claude is only available in certain regions right now.
FLY>PS: На счет ИИ. Когда я гуглил решение этого вопроса, мне в разделе "Обзор от ИИ" были предложены варианты, которые я уже пробовал и написал здесь (т.е. не рабочие). Но это уже тема для отдельного форума.
Извиняюсь, я думал share links работают. Скопировал сюда. По виду вроде норм.
вот
Проблема, с которой вы столкнулись, связана с тем, что скрипты, добавленные динамически через `createElement`, выполняются асинхронно, даже при установке `async = false`. Это поведение отличается от статически объявленных скриптов в HTML.
Вот несколько способов решения этой задачи:
## Способ 1: Использование `async = false` с правильным порядком
```javascript
// script1.js
let script2 = document.createElement("script");
script2.src = "script2.js";
script2.async = false; // Важно для сохранения порядка выполнения
// Добавляем скрипт ПЕРЕД script3.js в DOM
let script3 = document.querySelector('script[src="script3.js"]');
document.head.insertBefore(script2, script3);
```
## Способ 2: Удаление и повторная вставка script3.js
```javascript
// script1.js
let script3 = document.querySelector('script[src="script3.js"]');
let script3Parent = script3.parentNode;
// Удаляем script3 из DOM
script3.remove();
// Создаем и добавляем script2
let script2 = document.createElement("script");
script2.src = "script2.js";
script2.async = false;
document.head.appendChild(script2);
// После загрузки script2, добавляем script3 обратно
script2.onload = function() {
let newScript3 = document.createElement("script");
newScript3.src = "script3.js";
newScript3.async = false;
script3Parent.appendChild(newScript3);
};
```
## Способ 3: Загрузка через fetch и eval (не рекомендуется)
```javascript
// script1.js
fetch('script2.js')
.then(response => response.text())
.then(code => {
eval(code); // Выполняем код синхронно
// script2.js уже выполнен, script3.js выполнится следующим
});
```
## Способ 4: Использование модулей (современный подход)
Если возможно изменить архитектуру, рассмотрите использование ES6 модулей:
```html
<!DOCTYPE html>
<html>
<head>
<script type="module" src="script1.js"></script>
</head>
<body>
</body>
</html>
```
```javascript
// script1.js
import './script2.js';
import './script3.js'; // Будет выполнен после script2.js
```
## Рекомендация
Наиболее надежным решением будет **Способ 2**, так как он гарантирует правильный порядок выполнения. Способ 1 может не работать во всех браузерах из-за особенностей обработки динамически добавленных скриптов.
Также стоит отметить, что в вашем HTML есть опечатка: должно быть `src=` вместо `scr=` в тегах script.
Re[4]: Загрузка и выполнение скрипта2 из скрипта1 перед срип
Здравствуйте, bnk, Вы писали:
bnk>Вот несколько способов решения этой задачи: bnk>## Способ 1: Использование `async = false` с правильным порядком bnk>let script3 = document.querySelector('script[src="script3.js"]'); bnk>document.head.insertBefore(script2, script3);
bnk>## Способ 2: Удаление и повторная вставка script3.js bnk>let script3 = document.querySelector('script[src="script3.js"]'); bnk>// Удаляем script3 из DOM bnk>script3.remove();
Ну вот, что я и говорил на счет ИИ. На момент выполнения script1.js в DOM еще нет script3.js. По этому ни удалить его, ни вставить перед ним не получится. Вернее вставить можно, как я писал в самом начале обычным appendChild, а не так сложно как предлагает ИИ. Но это ничего не дает, кроме того, что в итоговом HTML он будет стоять на этом месте. Вот только выполнятся они будут в порядке будет: script1.js, script3.js, script2.js
bnk>## Способ 3: Загрузка через fetch и eval (не рекомендуется)
Eval я в стартовом сообщении не указывал, но его тоже хотелось бы избежать.
bnk>Если возможно изменить архитектуру, рассмотрите использование ES6 модулей:
Не могу, оно еще и на IE11 работать должно. Кстати, в нем скрипты выполняются в том порядке, в котором мне нужно.
UPD: а можешь у него переспросить на счет первых двух способов — не ошибся ли он, т.к. script3.js еще быть не должно.
Здравствуйте, rFLY, Вы писали:
FLY>UPD: а можешь у него переспросить на счет первых двух способов — не ошибся ли он, т.к. script3.js еще быть не должно.
Да ты прав. Попробовал попинать чисто из спортивного интереса. Как насчет такого:
-------------------- test.html
<!DOCTYPE html>
<html>
<head>
<script src="script1.js"></script>
<script src="script3.js"></script>
</head>
<body>
</body>
</html>
------------------------ scrtipt1.js
console.log('script1');
// Load script2.js synchronously using XMLHttpRequest and execute with script element
var xhr = new XMLHttpRequest();
xhr.open('GET', 'script2.js', false); // false = synchronous
xhr.send(null);
if (xhr.status === 200) {
var script = document.createElement('script');
script.textContent = xhr.responseText;
document.head.appendChild(script);
document.head.removeChild(script); // Clean up
}
// Rest of script1 code here - script3.js will execute after this script completes
------------------ script2.js
console.log('script2');
// -------------- script3.js
console.log('script3');
// -------------------- output --------------
script1
script2
script3
Здравствуйте, bnk, Вы писали:
bnk>Да ты прав. Попробовал попинать чисто из спортивного интереса. Как насчет такого:
Интересный подход. Правда в современном браузере, в отличии от старенького IE11, отдебажить вставленный таким образом скрипт не получится (его тупо нет в сорцах), но работает. Спасибо.
PS: Забавно, все хаят IE, конечно есть за что, но решение этой задачки на нем выглядит проще и логичнее, на мой взгляд. К тому же даже с последним вариантом остается возможность увидеть в чем и где ошибка и поставить брейкпоинты без добавления debugger,
Нашел способ как показать во вкладке sources встраиваемый таким образом скрипт. В начале файла скрипта надо написать
//@ sourceURL=myscript.js
где за "=" имя под которым будет отображаться скрипт в этой вкладке. И теперь с ним можно работать как обычно — просматривать, ставить точки остановки и т.п.
Этой директивой поменять имя в этой вкладке можно для любого файла, не важно добавлен ои он динамически или был со страницей.