Когда сценарий прерывает другой сценарий

В спецификации WHATWG есть интересный этап подготовки элемента сценария:

В противном случае немедленно выполните элемент сценария el, даже если другие сценарии уже выполняются.

Что это за случай? Как один скрипт может приостановить выполнение другого скрипта?

Это как если бы содержимое второго скрипта было внутри первого скрипта.

Barmar 28.05.2024 20:08

@Barmar Я понимаю это, но я хочу знать, что об этом говорит спецификация; каков реальный код этого примера?

MaximPro 28.05.2024 20:15

Я думаю, что единственный случай, когда это происходит во время выполнения другого скрипта, — это когда скрипт делает что-то вроде script document.createElement("script"); script.src = "URL"; document.body.appendChild(script);. Интерпретатор просто блокируется до тех пор, пока сценарий не будет получен, выполняет содержащийся в нем код, а затем возобновляет работу с того места, где он остановился.

Barmar 28.05.2024 20:20

@Barmar Нет, элементы сценария, вставленные в DOM, не блокируются.

Bergi 28.05.2024 20:22

@Bergi Конечно, ты прав. Вот почему вам нужно использовать прослушиватель событий load для кода, который зависит от этого скрипта.

Barmar 28.05.2024 20:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
5
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Учитывая ограничения, это скрипт, который не является модулем, не имеет атрибута src и вставляется во время выполнения скрипта. Я думаю, что следующий пример подходит:

<script>
console.info("before");
document.write(`<script>
console.info("nested");
</script>`);
console.info("after");
</script>

хм, я пытался привести тот же пример, но </script>. Почему это так важно?

MaximPro 28.05.2024 20:43

Вы имеете в виду опустить это?

Bergi 28.05.2024 20:57

Я имею в виду </script> вместо </script> в document.write

MaximPro 28.05.2024 21:11

@MaximPro Символ «\» используется для экранирования специальных символов и обозначает, что следующий символ «/» следует понимать буквально, независимо от контекста, он может означать что-то другое. Иногда это считается хорошей практикой, хотя здесь, насколько я вижу, в этом нет необходимости, поскольку «/» в этом контексте не имеет особого значения.

Daniel Cruz 28.05.2024 21:20

@DanielCruz Попробуйте без... :)

Keith 28.05.2024 21:21

@DanielCruz это имеет значение, протестируй без обратной косой черты

MaximPro 28.05.2024 21:21

@MaximPro, Кей, я понимаю, значит, это зависит от контекста выполнения? Я тестировал консоль разработчика браузера, и она отлично работает как с ней, так и без нее. Извините, если я неправильно информировал :(

Daniel Cruz 28.05.2024 21:27

@DanielCruz Да, я думаю, что здесь парсер HTML и парсер JS борются друг с другом, в чистом JS все в порядке.

Keith 28.05.2024 21:29

@DanielCruz, если честно, я не знаю, почему в document.write нужно писать обратную косую черту, правила парсера об этом ничего не говорят, по крайней мере, я не видел.

MaximPro 28.05.2024 21:31

@MaximPro Парсер HTML здесь довольно тупой, у вас есть открывающий тег <script>, он соответствует </script> , он ничего не знает о Javascript, поэтому ничего не знает о литералах шаблона или строковых литералах, он просто ищет </script>.. Экранирующий Берги поставил предотвращает совпадение первого тега <script> с внутри части Javascript.

Keith 28.05.2024 21:34

@Кейт, как парсер интерпретирует </script>? это не соответствует </script>

MaximPro 28.05.2024 21:39

Аааа @Кейт, я понимаю, поэтому экранирование сделано для того, чтобы парсер HTML понимал, что тег сценария не закрывается внутри строкового литерала. Как только js сможет проанализировать содержимое, для него это то же самое «/», что и «/», но необходимо выполнить экранирование, чтобы предотвратить преждевременное закрытие тега сценария во время анализа HTML?

Daniel Cruz 28.05.2024 21:43

@MaximPro Да, как сказал Кит, </script> используется для того, чтобы парсер html не интерпретировал его как закрывающий тег внешнего скрипта. Затем интерпретатор JavaScript создаст из этого кода обычное строковое значение </script>, которое запишется в документ. Есть много способов снять шкуру с этого кота , например с помощью '<'+'/script>', ответный подход самый короткий (и самый коварный). Довольно стандартный шаблон из былых времен, когда загрузка скриптов через document.write была обычным явлением :-)

Bergi 28.05.2024 21:51

@Bergi Keith, спасибо, я бы удалил свой комментарий, но тогда ваши комментарии будут вырваны из контекста, поэтому я просто отредактирую, чтобы указать, чтобы прочитать комментарии ниже. * Редактировать: я не могу редактировать свой комментарий :'( кажется, редактировать можно только в течение определенного периода после комментария.

Daniel Cruz 28.05.2024 21:55

@Bergi, точно, когда анализатор просматривает входной поток, он обнаруживает, что его закрывающий тег находится в document.write, но document.write еще не выполнен. Таким образом, остальная часть сценария оказывается вырванной из контекста.

MaximPro 28.05.2024 22:07

@Bergi исправьте свой ответ, вы написали «не вставлено в парсер», но оно «вставлено в парсер», иначе скрипты будут выполняться последовательно

MaximPro 29.05.2024 03:01

@MaximPro На самом деле я думал избежать условия, описанного в пункте 34.2., но на самом деле я не знаю, как создать таблицу стилей, блокирующую сценарии. Кроме того, когда когда-либо вызывается подготовка элемента сценария для элемента, не вставленного в анализатор?

Bergi 29.05.2024 09:51

@Bergi, кстати, я нашел ошибку в Chrome, уровень вложенности скриптов для вложенных скриптов всегда будет больше 1, поэтому это должно быть в случае прерывания родительского скрипта, но если вы вставите внешнюю таблицу стилей перед скриптом в document.write, вы получите выполнение скриптов последовательно, пример, Firefox в этом случае работает корректно в отличие от Chrome

MaximPro 29.05.2024 20:19

@MaximPro Могу поклясться, что я попробовал это - мне не пришло в голову, что это может быть ошибка браузера! Что касается скриптов, не вставленных в парсер (встроенных), я думал, что они вообще не будут выполняться, но, видимо, я перепутал добавление DOM с .innerHTML и .insertAdjacentHTML, поэтому мой эксперимент провалился.

Bergi 29.05.2024 20:34

@Bergi, когда парсер HTML встречает токен <script>, он устанавливает для флага элемента сценария значение, которое уже началось, равным true , что не позволяет подготовить элемент сценария, даже когда сценарий узла будет вставлен в DOM после анализа фрагмента процесс, поэтому innerHTML не вызывает скрипт (на всякий случай добавил этот комментарий).

MaximPro 29.05.2024 23:10

Другие вопросы по теме