Codemirror编辑器在单击之前不会加载内容


78

我正在使用codemirror 2,它的工作正常,除了在单击编辑器并使其成为焦点之前,不会将编辑器的设置值加载到编辑器中。

我希望编辑器无需单击即可显示其本身的内容。有任何想法吗?

所有的codemirror演示都按预期工作,因此我认为也许textarea没有集中精力,所以我也尝试过。

$("#editor").focus();
var editor =    CodeMirror.fromTextArea(document.getElementById("editor"), {
                    mode: "text/html",
                    height: "197px",
                    lineNumbers: true
                });

3
我在模态弹出窗口上加载CodeMirror编辑器时也遇到了这个问题。您是否找到了一种解决方案,以使编辑器聚焦?谢谢。

Answers:


54

您必须在setValue()之后调用refresh()。但是,在CodeMirror / Browser根据新内容更新布局之后,必须使用setTimeout将refresh()推迟到:

codeMirrorRef.setValue(content);
setTimeout(function() {
    codeMirrorRef.refresh();
},1);

这对我来说很有用。我在这里找到了答案。


1
我在jQuery UI选项卡上遇到了同样的问题,它对我有帮助。
greenif 2015年

如果可以的话,我会投票10次。拯救了我的一天。
jonathana

28

我希望您(或您加载的某些脚本)以某种方式干预DOM,以便在创建时隐藏编辑器或将其放置在奇怪的位置。refresh()使其可见后,将需要对其方法进行调用。


感谢您的回复,我也将尝试尝试。
卡尔

2
在我的实现中,display: none;导致该问题的父对象开始了-该答案可以轻松解决问题!谢谢@Marijn!
Soleil 2012年

这也解决了我的情况,父元素是GWT TabLayoutPanel或DisclosurePanel,可切换其子级的显示。我在这些父面板上使用侦听器修复了该问题,并在显示它时推迟了代码镜像的刷新。
jolivier13年

27

以防万一,对于那些没有足够仔细地阅读文档的人(例如我),但偶然发现这一点。有一个自动刷新插件

您需要添加autorefresh.js文件。现在,您可以像这样使用它。

var editor = CodeMirror.fromTextArea(document.getElementById("id_commentsHint"), {
  mode: "javascript",
  autoRefresh:true,
  lineNumbers: false,
  lineWrapping: true,

});

奇迹般有效。


这对我有用。setTimeout在内部使用实际时间是不可预测的,这是到目前为止对我唯一有效的方法。该解决方案更加健壮。
intcreator's

仅当我有一个setValue()时,这才对我有用。但是,如果我想多次设置该值,则仍然必须手动聚焦CodeMirror编辑器。
克里斯(Chris)2007年

@phpheini我也有同样的问题。您是否找到解决此问题的方法?
pricalaticorb

我确实没有解决方案,但是就我而言,我使用不同的标签来组织我的网站内容。因此,我将编辑器放在另一个选项卡中,然后当用户更改选项卡时,我调用codeMirror.refresh()函数来刷新编辑器。
克里斯(Chris

这对我不起作用。自动刷新插件可以工作(更改文档不再需要刷新),但是当编辑父级以开头时display: none,我仍然必须单击编辑器以使文本出现
Lewy Blue

10

我碰巧在引导选项卡中使用CodeMirror。我怀疑引导程序选项卡是阻止其显示直到被单击的原因。我通过简单地refresh()在show上调用方法来解决此问题。

var cmInstance = CodeMirror.fromTextArea(document.getElementById('cm'), {
    lineNumbers: true,
    lineWrapping: true,
    indentUnit: 4,
    mode: 'css'
});

// to fix code mirror not showing up until clicked
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function() {
    this.refresh();
}.bind(cmInstance));

1
我一直在寻找这个。谢谢。CodeMirror和Bootstrap选项卡需要此
FilT

5

有些东西对我有用。

$(document).ready(function(){
                var editor = CodeMirror.fromTextArea(document.getElementById("code2"), {
                     //lineNumbers: true,
                      readOnly: true,
                      autofocus: true,
                     matchBrackets: true,
                     styleActiveLine: true
                 });
                 setTimeout(function() {
                     editor.refresh();
                    }, 100);

        });


1

另一个解决方案(我也意识到,因为需要可见才能正确创建编辑器),是在构造过程中将父元素临时附加到body元素,然后在完成后重新附加。

这样,您就无需干预元素,也不必担心编辑器可能被掩埋的任何现有层次结构中的可见性。

就我而言,对于processr.com,我有多个嵌套的代码编辑元素,所有这些元素都需要在用户进行更新时即时创建,因此我要执行以下操作:

this.$elements.appendTo('body');
for (var i = 0; i < data.length; i++)
{
    this.addElement(data[i]);
}
this.$elements.appendTo(this.$view);

它的效果很好,到目前为止,还没有可见的闪烁或类似现象。


1

我正在与react一起工作,所有这些答案都对我不起作用...阅读文档后,它的工作方式如下:

在构造函数中,我初始化了一个代码Mirror的实例:

this.mirrorInstance = null;

在打开包含codeEditor的选项卡时,我在1 millisecocnd之后刷新了实例:

toggleSubTab() {
    setTimeout(() => {
      this.mirrorInstance.refresh();
    }, 1);
  }

这是JSX代码:

<CodeMirror
           value={this.state.codeEditor}
           options={{
           mode: "htmlmixed",
           theme: "default",
           lineNumbers: true,
           lineWrapping: true,
           autoRefresh: true
           }}
           editorDidMount={editor => {
           this.mirrorInstance = editor;
           }}
        />

0

尝试将焦点放在DOM元素而不是jQuery对象上。

var editor=$( '#editor' );
editor[0].focus();
// or
document.getElementById( 'editor' ).focus();

感谢您的回复,我将尝试尝试。
卡尔

0

我今天晚上自己遇到了这个问题。

许多其他帖子都认为textarea父级的可见性很重要,如果隐藏它,则可能会遇到此问题。

在我的情况下,表单本身和周围的环境都很好,但是我在渲染链上游的Backbone视图管理器是问题所在。

在视图完全呈现自身之前,我的view元素不会放置在DOM上,因此我猜未在DOM上的元素被认为是隐藏的或只是未处理。

为了解决这个问题,我添加了一个后期渲染阶段(伪代码):

view.render();
$('body').html(view.el);
view.postRender();

在postRender中,视图现在可以在屏幕上可见,因此视图可以执行所需的操作,这是我移动CodeMirror并可以正常工作的地方。

这也可以用某种方式来解释为什么有人可能会遇到诸如弹出窗口之类的问题,因为在某些情况下,他们可能会尝试在显示之前构建所有内容。

希望能对某人有所帮助。

托比


0
<div class="tabbable-line">
    <ul class="nav nav-tabs">
        <li class="active">
            <a href="#tabXml1" data-toggle="tab" aria-expanded="true">Xml 1</a>
        </li>
        <li class="">
            <a href="#tabXml2" id="xmlTab2Header" data-toggle="tab" aria-expanded="true">Xml 2</a>
        </li>
    </ul>
    <div class="tab-content">
        <div class="tab-pane active" id="tabXml1">
            <textarea id="txtXml1" />
        </div>
        <div class="tab-pane" id="tabXml2">
            <textarea id="txtXml2" />
        </div>
    </div>
</div>

<link rel="stylesheet" href="~/Content/codemirror.min.css">
<style type="text/css">
    .CodeMirror {
        border: 1px solid #eee;
        max-width: 100%;
        height: 400px;
    }
</style>

<script src="~/Scripts/codemirror.min.js"></script>
<script src="~/Scripts/codemirror.xml.min.js"></script>
<script>
        $(document).ready(function () {
            var cmXml1;
            var cmXml2;
            cmXml1 = CodeMirror.fromTextArea(document.getElementById("txtXml1"), {
                mode: "xml",
                lineNumbers: true
            });
            cmXml2 = CodeMirror.fromTextArea(document.getElementById("txtXml2"), {
                mode: "xml",
                lineNumbers: true
            });
            // Refresh code mirror element when tab header is clicked.
            $("#xmlTab2Header").click(function () {
                setTimeout(function () {
                    cmXml2.refresh();
                }, 10);
            });
        });
</script>

0

对我有用的东西!:)

      var sh = setInterval(function() {
       agentConfigEditor.refresh();
      }, 500); 

      setTimeout(function(){
        clearInterval(sh);  
      },2000)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.