CodeMirror textarea的多个实例位于同一页面上

时间:2017-12-21 22:09:44

标签: javascript html codemirror

我正在尝试为面试问题制作一个小项目,并在页面上提供一系列问题以及答案和代码示例。每个都在Materialise.css的.collapsible div中,当点击时显示答案和代码示例。

最好的方法是什么?我尝试将初始化程序放入一个函数中,从DOM中获取所有textareas,循环遍历它们并将它们转换为CodeMirror textareas。

$(document).ready(function(){

  var blocks = document.getElementsByClassName('code-block');

  function createEditorFrom(selector) {
    let editor = CodeMirror.fromTextArea(selector, {
      lineNumbers : false,
      mode: "swift",
    });
  }

  for (var x = 0; x < blocks.length; x++) {
    createEditorFrom(blocks[x]);
  }

  // Callback for Collapsible open
  $('.collapsible').collapsible({
    onOpen: function() { 
      // call editor.refresh()?
    },
  });

});

这确实有效,但我觉得这不是一个解决这个问题的非常优雅的方法。有更好的方法吗?

问题:

  1. 是否有更好的方法来创建所有CodeMirror textareas?
  2. 编辑器中的代码在点击之前不会显示。我没有做任何事情让它发挥作用。调用editor.refresh()(使用setTimeout)和autorefresh:true。

2 个答案:

答案 0 :(得分:0)

无论如何,您必须要做的是保持对CodeMirror实例的引用(例如,获取/设置它们的值),因此createEditorForm必须返回CodeMirror实例,&amp;例如,你可以将它们推送到循环中的数组:

function createEditorFrom(selector) {
  return CodeMirror.fromTextArea(selector, {
    lineNumbers : false,
    mode: "swift",
  });
}

let codeblocks = [];
for (var x = 0; x < blocks.length; x++) {
  codeblocks.push({
     CM: createEditorFrom(blocks[x]), 
     el: blocks[x]
  });
}

我遇到了类似的问题“编辑器中的代码直到点击”才出现,我甚至在解决方案旁边写了一条评论。转换为您的实现:

function createEditorFrom(selector) {
  var instance = CodeMirror.fromTextArea(selector, {
    lineNumbers : false,
    mode: "swift",
  });
  // make sure the CodeMirror unit expands by setting a null character
  instance.setValue('\0');
  instance.setValue('');
  return instance;
}

为了它的价值,我还使用了一些CSS调整来确保初始和一致性。最大高度渲染:

/* CodeMirror */
.CodeMirror { height: auto; overflow: auto; max-height: 250px; }
.CodeMirror-scroll { height: auto; min-height: 24px; }

是否有更好的方法来创建所有CodeMirror textareas [而不是通过它们循环]?

是的,如果它们在页面加载时不可见,你可以延迟初始化它们(实际上我认为只有当<textarea>的父节点可见时才更好地初始化它们,我不确定CodeMirror是否需要render-info(如Element.getBoundingClientRect),例如只加载他们可折叠父级的onOpen

答案 1 :(得分:0)

当打开可折叠的时候,我最终初始化了每一个。这有效但我想如果在同一个可折叠中有多个CodeMirror textareas,则需要进行调整。

我还添加了一个支票,否则当折叠打开,然后关闭,然后重新打开它会创建一个重复的textarea。

$(document).ready(function(){

  $('.collapsible').collapsible({
    onOpen: createCodeBlock
  });

  function createCodeBlock(target) {
    var card     = target.context.parentElement.parentElement;
    var textarea = card.getElementsByClassName('code-block')[0];

    // Placeholder class that prevents the duplicate creation of
    // the same textarea when the collapsible is closed then reopened.
    if (!textarea.classList.contains("created")) {
      CodeMirror.fromTextArea(textarea, {
        lineNumbers: false,
        mode: "swift",
      });
      textarea.className += "created";
    }
  }

});