CodeMirror,在 keyup 上更新 iframe 脚本

CodeMirror, updating iframe script on keyup

我有一个带有 codemirror 编辑器和 iframe 的小部件,我正在附加一个带有预定义内容的脚本标签。

我正在尝试更新 keyup 上的脚本标签内容,这是有效的,但它实际上不是 "updating" javascript。

解释一下:预定义代码有一个点击事件,将sample-div背景颜色更改为蓝色,如果我编辑代码而不是更改color 变为蓝色,当我单击 sample-div 时,它会将背景 颜色都更改为蓝色。

这很奇怪,因为 iframe 脚本标签得到了正确的 "text"。

由于某种原因无法在代码段中工作,所以这里是 fiddle https://jsfiddle.net/hannacreed/tkp5c017/3/

javascript "code" 正在更新,但您忽略了示例代码绑定到文档的已委托事件。

文档上的任何后续委托事件将简单地"append"到已经绑定的事件。这就是为什么尽管可见的 "code" 发生了变化,您还是看到以前的处理程序额外触发的原因。

每次要更新代码时只需 "reload" iframe。重新加载是指重新创建 iframe 元素。当然,这在 keyup 上可能会很昂贵,因此您可能还想考虑限制重新加载。

请参阅 this forked fiddle 了解工作版本。

本质上,您需要一个生成 iframe 内容的函数...

function getFrameContents() {
  return `<!doctype html>
<html>
<head>
    <style>body { background: #fff; } .sample-div { background: #333; padding: 10px; width: fit-content; height: fit-content; border-radius: 10px; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);</style>
    <script>window.$ = parent.$;<\/script>
    <script>${editor.getValue().toString()}<\/script>
</head>
<body>
  <div class="wrapper">
      <div class="sample-div"><label>here is some text.</label></div>
  </div>
</body>
</html>`;
}

您还需要一个函数来创建新的 iframe 代替旧的 iframe,用生成的内容替换文档(根据调用上述函数)。

function reloadFrame () {
  var iframe = widget.find('iframe').replaceWith(document.createElement('iframe'));
  iframe = widget.find('iframe');
  var doc = iframe.contents()[0];
  var contents = getFrameContents();
  doc.open();
  doc.writeln(contents);
  doc.close();
}

最后,在加载和 keyup 时调用 reloadFrame(考虑节流)。

// load initial frame
reloadFrame();

// trigger reload on keyup
$(document).on('keyup', '.CodeMirror', function () {
    reloadFrame();
});