最近做了一个JS在线练习页面,要求在一个编辑框中输入代码,执行并呈现结果。
制作过程中发现了以下问题:
1、如果输入的代码中使用了 document.write() 输出结果,执行后会清空当前页面。
解决方法:用写入innerHTML替换write(),虽然还存在清除结果块中其它内容的bug,但不会清除页面了。
2、如果输入的代码中有函数,函数调用时会产生 undefined 错误。
解决方法:先生成一个<script>标签,再把文本域中的JS代码提取出来写在这个标签内,问题就消失了。
以下是页面效果:
左边是一个textarea文本域,里面可以事先放置代码,也可以修改和输入新代码。代码中可包括HTML、CSS和Javascript、jQuery。
右边是当前的实时效果,修改代码后,单击空白处就可看到即时效果。
CSS:
<style>
.test_box{
min-width: 400px;
height: 400px;
display: flex;
}
#code{
flex: 1;
height: 100%;
background-color: #2d3143;
color: white;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 16px;
}
#result{
flex: 1;
height: 100%;
border: solid 1px #bbbbbb;
}
</style>
HTML:
<div>单击按钮放大文字:</div>
<div class="test_box">
<textarea id="code" onchange="runCode()"><style>
#a{
color: red;
}
</style>
<input type="button" value="放大" onclick="maFontSize()">
<div id="a" style="font-size: 16px">你好</div>
<script>
function maFontSize() {
var a = document.getElementById("a");
var s = parseInt(a.style.fontSize)+3;
a.style.fontSize = s+"px";
}
</script>
</textarea>
<div id="result"></div>
</div>
其中<textarea>标签内放置的是预先给定的代码。
JS:
<script>
//执行textarea文本域内代码
function runCode() {
var t = document.getElementById("code").value;
var js = t.match(/<script>([\s\S]*?)<\/script>/i); //提取JS代码
if(js){
t = t.substring(0,js.index)+t.substring(js.index+js[0].length);
document.getElementById("result").innerHTML = t; //写入非JS代码
var j = js[1].replace(/document *\. *write/g,"document.getElementById('result').innerHTML = ");
var newScript = document.createElement("script"); //创建<script>标签
newScript.innerHTML = j;
document.getElementById("result").appendChild(newScript); //写入JS代码
}else {
document.getElementById("result").innerHTML = t;
}
}
runCode(); //打开页面时执行文本域内已经存在的代码
</script>
以上程序还存在一个bug,在文本域中只能用<script>标签定义JS程序,不能写成<script type=“text/javascript”>