我正在尝试创建一个html / css / javascript在线编辑器,供人们尝试使用小代码和类似的东西。
它实际上非常简单..你创建2 div
' s是textarea
id="input"
而另一个是div
id="output"
而你创建一个js函数,通过按下按钮将输入的内容推送到输出中,或者通过每2秒运行一次该函数使其生效
我运行代码,它适用于html和css,但是一旦我尝试在<script>
里面的textarea
标签内创建一个函数,它实际上并没有运行..就像它没有&#39;存在..
我可以使用按钮运行小函数,如果我在onclick
内编写动作但是定义一个函数,然后通过该按钮运行它不起作用
window.setInterval(function(){
var y = document.getElementById("automatic").checked
if (y==1){
editorFunction()
}
}, 1000);
function editorFunction(){
var x = document.getElementById("input").value;
document.getElementById("output").innerHTML = x;
}
我的问题是......有没有办法解决这个问题? 我真的希望页面保持静态..我不想将内容发送到数据库并创建一个新表单并在页面上呈现它...我想保持它尽可能简单 有人要求提供HTML ..我不认为这很重要但是在这里:
<body id="body">
<section class="container">
<div class="row">
<div class="col-sm-6">
<textarea class="col-sm-12" id="input"></textarea>
</div>
<div class="col-sm-6">
<div class="col-sm-12" id="output"></div>
</div>
</div>
</section>
<section>
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-6">
<button onclick="editorFunction()">RUN</button>
<input type="checkbox" id="automatic" checked>Submit the changes LIVE</input>
</div>
</div>
</section>
</body>
eval()仅在我想执行某个动作时才有效。我无法真正定义一个将留待以后使用的功能
答案 0 :(得分:1)
根据Denis Ivanov的建议,我提出了这个解决方案:
function editorFunction(){
var x = document.getElementById("input").value;
var output=document.getElementById("output");
output.innerHTML = x;
var scripts=output.getElementsByTagName("SCRIPT");
for (var i=0;i<scripts.length;i++)
{
var script=scripts[i];
eval(script.textContent);
}
}
但是我对自动模式有疑问:显然,当用户编写脚本函数时,它还不应该被测试。
<强>更新强>
支持定义功能(基于Makyen的建议):
function editorFunction(){
var x = document.getElementById("input").value;
var output=document.getElementById("output");
output.innerHTML = x;
var scripts=output.getElementsByTagName("SCRIPT");
for (var i=0;i<scripts.length;i++)
{
var script=scripts[i];
var x=eval(script.textContent);
var scriptNew=document.createElement("SCRIPT");
scriptNew.type=script.type;
scriptNew.textContent=script.textContent;
script.parentNode.insertBefore(scriptNew, script);
script.parentNode.removeChild(script);
}
}
答案 1 :(得分:1)
您需要专门处理<script>
标记。作为文本插入的内容(例如innerHTML
)被特别排除在运行脚本之外。这是security reasons。
您可以使用innerHTML
插入文字,然后在使用<script>
创建新标记的同时删除插入的document.createElement('script')
标记,在其中添加脚本的textContent
标记您正在删除。然后将新创建的<script>
标记插入文档
window.setInterval(function(){
var y = document.getElementById("automatic").checked
if (y==1){
editorFunction()
}
}, 1000);
function editorFunction(){
var x = document.getElementById("input").value;
var outputEl = document.getElementById("output");
outputEl.innerHTML = x;
//Get a NodeList of the <script> elements
var scripts = outputEl.querySelectorAll('script');
for(var i=0;i<scripts.length;i++){
var oldScript = scripts[i];
var newScript = document.createElement('script');
//Copy the actual script
newScript.textContent = oldScript.textContent;
//Copy the oldScripts attributes
var attrs = oldScript.attributes;
for(var j=0;j<attrs.length;j++){
newScript.setAttribute(attrs[j],oldScript.getAttribute(attrs[j]));
}
//Replace the non-functional oldScript with the newScript
oldScript.parentNode.replaceChild(newScript,oldScript);
}
}
<body id="body">
<section class="container">
<div class="row">
<div class="col-sm-6">
<textarea class="col-sm-12" id="input"></textarea>
</div>
<div class="col-sm-6">
<div class="col-sm-12" id="output"></div>
</div>
</div>
</section>
<section>
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-6">
<button onclick="editorFunction()">RUN</button>
<input type="checkbox" id="automatic" checked>Submit the changes LIVE</input>
</div>
</div>
</section>
</body>
建议更改:
<script>console.log('This is a test');</script>
它将重复输出到控制台。
var detectScriptRegExp = /<script/ig;
document.getElementById("input").addEventListener('input',function(){
var autoCheckboxEl = document.getElementById("automatic");
if (autoCheckboxEl.checked==true){
editorFunction();
}else if (autoCheckboxEl.disabled==true){
detectScriptRegExp.lastIndex=0; //clear the RegExp
if(!detectScriptRegExp.test(document.getElementById("input").value)){
//Don't lock out LIVE if there is no <script>
autoCheckboxEl.disabled=false;
}
}
}, false);
function editorFunction(){
var autoCheckboxEl = document.getElementById("automatic");
autoCheckboxEl.disabled = false;
var x = document.getElementById("input").value;
var outputEl = document.getElementById("output");
outputEl.innerHTML = x;
//Get a NodeList of the <script> elements
var scripts = outputEl.querySelectorAll('script');
for(var i=0;i<scripts.length;i++){
var oldScript = scripts[i];
var newScript = document.createElement('script');
//Copy the actual script
newScript.textContent = oldScript.textContent;
//Copy the oldScripts attributes
var attrs = oldScript.attributes;
for(var j=0;j<attrs.length;j++){
newScript.setAttribute(attrs[j],oldScript.getAttribute(attrs[j]));
}
//Replace the non-functional oldScript with the newScript
oldScript.parentNode.replaceChild(newScript,oldScript);
//Disable auto/live updates when there are scripts.
// This is needed, at least in a snippet. If you use console.log()
// the checkbox will rapidly be covered.
autoCheckboxEl.checked = false;
autoCheckboxEl.disabled = true;
}
}
<body id="body">
<section class="container">
<div class="row">
<div class="col-sm-6">
<textarea class="col-sm-12" id="input"></textarea>
</div>
<div class="col-sm-6">
<div class="col-sm-12" id="output"></div>
</div>
</div>
</section>
<section>
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm-6">
<button onclick="editorFunction()">RUN</button>
<input type="checkbox" id="automatic" checked>Submit the changes LIVE</input>
</div>
</div>
</section>
<!-- Extra lines so we can scroll the snippet in case console output covers controls-->
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
</body>