我尝试开发一个实时代码编辑器。
代码给出了错误:
Uncaught SyntaxError: Unexpected end of input
问题出在哪里或者有什么解决办法?
function compile() {
let htmlContent = document.getElementById('html');
let cssContent = document.getElementById('css');
let jsContent = document.getElementById('js');
let output = document.getElementById('output');
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"></textarea>
<textarea id="css" cols="30" rows="10"></textarea>
<textarea id="js" cols="30" rows="10"></textarea>
<button onclick="compile()">Run</button>
<iframe id="output"></iframe>
答案 0 :(得分:0)
如果您在脚本标签内插入,无论它是引号中的字符串、撇号,甚至是模板文字,它都会关闭脚本标签。你必须逃避它。
doc.write(
`<style>${cssContent.value}</style>
<body>${htmlContent.value}</body>
<script>${jsContent.value}<\/script>`);
但是,如果您使用外部脚本,它应该可以正常工作而不会转义。
此处有更多讨论:"Unterminated template literal" syntax error when literal contains script tag
答案 1 :(得分:0)
关闭脚本标签
正如@Sanmeet 在他(已删除)的回答中指出的那样,错误是由于没有转义结束脚本标签中的反斜杠引起的:如果 html 解析器解码 <script>
标签,它会将输入缓冲到next </script>
标记并将其传递给 JavaScript 编译器。在这种情况下,它将脚本的剩余部分视为文本并将其放入 body 元素中。
重用变量名和类名
将结束标记转义为 <\/script>
揭示了另一个问题。当 document.open
被调用时,谷歌浏览器不会重新初始化全局变量空间(这是正确的历史做法)。遗憾的是,Firefox 已更改其行为以遵循套件并且不再重新初始化变量。
一种可能的解决方案是在每次点击 iframe
按钮时创建一个新的 run
元素。下面的示例扩展了发布的代码以创建新的 iframe
。如果您在 JavaScript 框中声明 let
、const
或 class
标识符,您现在可以重复按下运行按钮而无需更改变量和类名称。
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>
代码片段错误
执行该代码段会在尝试访问 doc
时产生安全错误。它在浏览器中按预期工作。