Я создаю интерактивный редактор кода, который состоит из текстового поля и элемента <iframe>
. Всякий раз, когда пользователь вводит код в текстовое поле, содержимое IFrame записывается, а тег <script>
внутри IFrame заполняется содержимым текстового поля кода, в результате чего введенный пользователем код запускается внутри IFrame. Каждый раз, когда пользователь печатает, IFrame должен быть сброшен / перезагружен, а документ снова записан с новым содержимым текстового поля в теге сценария IFrame, по сути, автоматически запуская любой код, который они печатают по мере его ввода.
Однако при этом я заметил, что конфликты пространства имен возникали как переменные, которые пользователь объявил бы в своем коде, которые будут сохраняться между обновлениями IFrame. Я исправил это, обернув вставленный код в IIFE, но затем заметил, что когда пользователь запустит al oop и затем дважды перезагрузит IFrame, будут запущены два цикла .
Очевидно, что JavaScript контекст IFrame не сбрасывается. Я попробовал ответы , приведенные здесь , включая перезагрузку IFrame с использованием .contentWindow.location.reload()
, а также изменение источника IFrame с помощью .src = "about:blank"
, но они просто сбрасывают содержимое документа, а не контекст IFrame JavaScript, который в соответствии с этими ответами сохраняются, если IFrame находится в том же домене.
Вот фактический код, с которым я работаю (клонировать репозиторий -> Выполнить npm install
-> Run npm run dev
-> Open examples/Sandbox/index.html
).
Вот минимальный воспроизводимый пример проблемы (основывается на существовании элемента IFrame с идентификатором frame
):
const frame = document.getElementById("frame");
let i = 1;
function updateFrame() {
frame.contentWindow.location.reload();
frame.contentDocument.open();
frame.contentDocument.write(`
<html>
<body>
<script>
(function() {
let a = 0;
function print() {
console.log(${i++} + ": " + a++);
requestAnimationFrame(print);
}
print();
})();
</script>
</body>
</html>
`);
frame.contentDocument.close();
}
updateFrame();
updateFrame();
См. На JSFiddle .
Обратите внимание, что updateFrame()
вызывается дважды, что должно перезагрузить содержимое IFrame, оставляя только второй запущенный l oop, однако оба цикла print()
одновременно печатаются на консоль, показывая, что контекст сохраняется во время перезагрузок.
Предполагаемое поведение состоит в том, что содержимое IFrame и контекст JavaScript Shoul будет полностью сброшен между перезагрузками. В этом примере, только 2: ...
должен многократно печататься на консоли вместо 1: ...
и 2: ...
. Как я могу перефразировать sh IFrame таким образом, чтобы его JavaScript контекст не сохранялся во время перезагрузок и по существу действует так же, как перезагрузка страницы вручную?