Closing the script tag
As pointed out by @Sanmeet in his (deleted) answer, the error is caused by not escaping the backslash in the end script tag: if the html parser decodes a <script>
tag, it buffers input up to the next </script>
tag and passes it to the JavaScript compiler. In this case it then treated what was left of the script as text an put it in the body element.
Reusing variable and class names
Escaping the end tag to <\/script>
reveals another problem. Google Chrome does not re-initialize global variable space when document.open
is called (as was correct historical practice). Sadly Firefox has altered its behavior to follow suite and no longer re-initializes variables either.
One possible solution is to create a new iframe
element each time the run
button is clicked. The example below extends the posted code to create a new iframe
. If you declare let
, const
or class
identifiers in the JavaScript box, you can now press the run button repeatedly without changing variable and class names.
function compile() {
let htmlContent = document.getElementById('html');
let cssContent = document.getElementById('css');
let jsContent = document.getElementById('js');
let output = document.getElementById('output');
let replacement = document.createElement('iframe');
replacement.id = "output";
output.replaceWith( replacement);
output = replacement;
output = output.contentWindow || output.contentDocument.document || output.contentDocument;
let doc = output.document;
doc.open();
doc.write(
`<style>${cssContent.value}</style>
<body>${htmlContent.value}</body>
<script>${jsContent.value}<\/script>`
);
doc.close();
}
<textarea id="html" cols="30" rows="10" placeholder="html..."></textarea>
<textarea id="css" cols="30" rows="10" placeholder="css..."></textarea>
<textarea id="js" cols="30" rows="10" placeholder="js..."></textarea>
<button onclick="compile()">Run</button>
<iframe id="output"></iframe>
Code Snippet Error
Executing the snippet generates a security error trying to access doc
. It works as intended in a browser.