Загрузка и выполнение скрипта2 из скрипта1 перед сриптом3
От: rFLY  
Дата: 10.08.25 11:14
Оценка:
Всем привет.

Допустим есть html:
<!DOCTYPE html>
<html>
   <head>
      <script scr="script1.js"></script>
      <script scr="script3.js"></script>
   </head>
   <body>
   </body>
</html>


Есть ли способ подключить в 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
От: bnk СССР http://unmanagedvisio.com/
Дата: 10.08.25 12:16
Оценка:
Здравствуйте, rFLY, Вы писали:

FLY>Есть ли способ подключить в script1.js скрипт script2.js не используя document.write для вставки и defer для scipt3.js так, чтобы он выполнился до scipt3.js?


Я в таких случаях теперь просто звоню Слоу спрашиваю Клода

https://claude.ai/share/a7767cfc-30a3-45a0-b197-a9fdcb91d2ea
Re[2]: Загрузка и выполнение скрипта2 из скрипта1 перед сриптом3
От: rFLY  
Дата: 10.08.25 12:38
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>Я в таких случаях теперь просто звоню Слоу спрашиваю Клода


bnk>https://claude.ai/share/a7767cfc-30a3-45a0-b197-a9fdcb91d2ea

Unfortunately, Claude is only available in certain regions right now.


PS: На счет ИИ. Когда я гуглил решение этого вопроса, мне в разделе "Обзор от ИИ" были предложены варианты, которые я уже пробовал и написал здесь (т.е. не рабочие). Но это уже тема для отдельного форума.
Re[3]: Загрузка и выполнение скрипта2 из скрипта1 перед сриптом3
От: bnk СССР http://unmanagedvisio.com/
Дата: 10.08.25 13:11
Оценка:
Здравствуйте, rFLY, Вы писали:

bnk>>Я в таких случаях теперь просто звоню Слоу спрашиваю Клода


bnk>>https://claude.ai/share/a7767cfc-30a3-45a0-b197-a9fdcb91d2ea

FLY>

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 перед срип
От: rFLY  
Дата: 10.08.25 13:39
Оценка:
Здравствуйте, 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 еще быть не должно.
Отредактировано 10.08.2025 13:42 rFLY . Предыдущая версия .
Re[5]: Загрузка и выполнение скрипта2 из скрипта1 перед срип
От: bnk СССР http://unmanagedvisio.com/
Дата: 10.08.25 14:53
Оценка: 6 (1)
Здравствуйте, 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
Отредактировано 24.11.2025 10:08 bnk . Предыдущая версия . Еще …
Отредактировано 24.11.2025 10:08 bnk . Предыдущая версия .
Re[6]: Загрузка и выполнение скрипта2 из скрипта1 перед срип
От: rFLY  
Дата: 10.08.25 15:48
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>Да ты прав. Попробовал попинать чисто из спортивного интереса. Как насчет такого:

Интересный подход. Правда в современном браузере, в отличии от старенького IE11, отдебажить вставленный таким образом скрипт не получится (его тупо нет в сорцах), но работает. Спасибо.

PS: Забавно, все хаят IE, конечно есть за что, но решение этой задачки на нем выглядит проще и логичнее, на мой взгляд. К тому же даже с последним вариантом остается возможность увидеть в чем и где ошибка и поставить брейкпоинты без добавления debugger,
Отредактировано 10.08.2025 16:09 rFLY . Предыдущая версия .
Re[7]: Добавление/изменение имени скрипта на вкладке sources
От: rFLY  
Дата: 17.08.25 13:33
Оценка: 84 (1)
Нашел способ как показать во вкладке sources встраиваемый таким образом скрипт. В начале файла скрипта надо написать
//@ sourceURL=myscript.js

где за "=" имя под которым будет отображаться скрипт в этой вкладке. И теперь с ним можно работать как обычно — просматривать, ставить точки остановки и т.п.
Этой директивой поменять имя в этой вкладке можно для любого файла, не важно добавлен ои он динамически или был со страницей.
Отредактировано 17.08.2025 13:39 rFLY . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.