如何将文本域转换成ACE编辑器?

99

我希望能够将页面上特定的文本区域转换为ACE编辑器。

请问有什么建议吗?

编辑:

我已经让editor.html文件在一个文本区域上运作良好,但当我添加第二个文本区域时,第二个区域没有被转换为编辑器。

编辑2:

我决定放弃使用多个编辑器,而是在新窗口中打开一个编辑器。我的新问题是,当我隐藏()和展示()文本区域时,显示效果出现问题。有任何想法吗?


1
这位大佬提供了一个非常棒的解决方案:https://gist.github.com/duncansmart/5267653 - But those new buttons though..
5个回答

166

据我理解Ace的想法,你不应该将 textarea 作为Ace编辑器本身。你应该创建一个额外的div,并使用 .getSession() 函数更新textarea。

HTML

<textarea name="description"/>
<div id="description"/>

JavaScript

var editor = ace.edit("description");
var textarea = $('textarea[name="description"]').hide();
editor.getSession().setValue(textarea.val());
editor.getSession().on('change', function(){
  textarea.val(editor.getSession().getValue());
});
或者只需调用
textarea.val(editor.getSession().getValue());

只有在提交包含给定文本区的表单时才会触发。我不确定这是否是使用Ace的正确方式,但这是在GitHub上使用的方式。


1
文本区域的值应该只在表单提交事件上更新,对吧?另外,根据这个链接:https://groups.google.com/group/ace-discuss/browse_thread/thread/6c32f9cf0fd8eaef,没有支持文本区域替换的功能。你的答案是正确的。谢谢。 - Damien
4
有时候你需要即时更新文本域的值,比如实现草稿自动保存等功能。 - installero
我有一个问题与这个方法:在 ace.editor 上测试 'SELECT 1 OR 2;' 会将 'SELECT&nbsp;1OR&nbps;2;' 放入文本区域。有人可以告诉我我做错了什么吗? - alexglue
alexglue,你在textarea上设置了white-space:nowrap吗? https://github.com/ajaxorg/ace/issues/900 - installero
安装者,我的文本区域上没有这个CSS属性。所以,不,我没有。 - alexglue
如果您计划实时更新文本区域,请注意您的JS代码可能会在Ace编辑器中的每次内容更改时执行。我曾经遇到过这种情况,并且在保存之前破坏了内容。如果您计划允许JavaScript,最好的测试方法是在script标签内执行“console.log(”test“)”。 - NXT

42
Duncansmart在他的github页面上有一个相当不错的解决方案,progressive-ace,展示了一种将ACE编辑器与页面连接起来的简单方法。基本上,我们获取所有带有data-editor属性的<textarea>元素,并将其转换为ACE编辑器。该示例还设置了一些您应根据自己喜好自定义的属性,并演示了如何使用data属性来针对每个元素设置属性,例如使用data-gutter显示和隐藏gutter。

// Hook up ACE editor to all textareas with data-editor attribute
$(function() {
  $('textarea[data-editor]').each(function() {
    var textarea = $(this);
    var mode = textarea.data('editor');
    var editDiv = $('<div>', {
      position: 'absolute',
      width: textarea.width(),
      height: textarea.height(),
      'class': textarea.attr('class')
    }).insertBefore(textarea);
    textarea.css('display', 'none');
    var editor = ace.edit(editDiv[0]);
    editor.renderer.setShowGutter(textarea.data('gutter'));
    editor.getSession().setValue(textarea.val());
    editor.getSession().setMode("ace/mode/" + mode);
    editor.setTheme("ace/theme/idle_fingers");

    // copy back to textarea on form submit...
    textarea.closest('form').submit(function() {
      textarea.val(editor.getSession().getValue());
    })
  });
});
textarea {
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js"></script>
<textarea name="my-xml-editor" data-editor="xml" data-gutter="1" rows="15"></textarea>
<br>
<textarea name="my-markdown-editor" data-editor="markdown" data-gutter="0" rows="15"></textarea>


4
强烈推荐。非常灵活和干净! - aaandre
5
我仅对上述代码进行了一处修改,将 "textarea.css('visibility', 'hidden')" 更改为 "textarea.css('display', 'none')"。否则,屏幕上会出现额外的空白空间。请注意,这并不会改变原有代码的含义。 - Nick Goloborodko
@NickGoloborodko - 迟了几年,但我同意并已相应更新答案。此外,修复了ace链接,因此片段可以再次正常工作。 - But those new buttons though..

8
您可以拥有多个Ace编辑器。只需为每个文本区域分配一个ID,并为两个ID创建一个Ace编辑器,如下所示:
<style>
#editor, #editor2 {
    position: absolute;
    width: 600px;
    height: 400px;
}
</style>
<div style="position:relative; height: 450px; " >
&nbsp;
<div id="editor">some text</div>
</div>
<div style="position:relative; height: 450px; " >
&nbsp;
<div id="editor2">some text</div>
</div>
<script src="ace.js" type="text/javascript" charset="utf-8"></script>
<script src="theme-twilight.js" type="text/javascript" charset="utf-8"></script>
<script src="mode-xml.js" type="text/javascript" charset="utf-8"></script>
<script>
window.onload = function() {
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/twilight");
    var XmlMode = require("ace/mode/xml").Mode;
    editor.getSession().setMode(new XmlMode());

    var editor2 = ace.edit("editor2");
    editor2.setTheme("ace/theme/twilight");
    editor2.getSession().setMode(new XmlMode());

};
</script>

1

创建编辑器只需执行以下操作:

HTML:

<textarea id="code1"></textarea>
<textarea id="code2"></textarea>

JS:

var editor1 = ace.edit('code1');
var editor2 = ace.edit('code2');
editor1.getSession().setValue("this text will be in the first editor");
editor2.getSession().setValue("and this in the second");

CSS:

#code1, code2 { 
  position: absolute;
  width: 400px;
  height: 50px;
}

它们必须明确地定位和调整大小。通过show()和hide(),我相信你指的是jQuery函数。我不确定它们是如何实现的,但它不能修改它在DOM中占用的空间。我使用以下方式进行隐藏和显示:

$('#code1').css('visibility', 'visible');
$('#code2').css('visibility', 'hidden');

如果您使用css属性"display",它将无效。
在此处查看维基以了解如何添加主题、模式等... https://github.com/ajaxorg/ace/wiki/Embedding---API 注意:它们不一定是文本区域,它们可以是您想要的任何元素。

8
不行。如果你调用 ace.edit('code1'),你会得到类似垃圾的东西:<textarea class="ace_editor ace-twilight ace_focus"><div class="ace_gutter">...</textarea> 换句话说,ace.edit 尝试将自己塞进文本区域,这样做不太好。 - Ciantic

1

对于只想要使用CDN中的Ace来实现最小化、可工作示例的任何人:

<!DOCTYPE html>
<html lang="en">

<body style="margin:0">
  <div id="editor">function () { 
  console.log('this is a demo, try typing!')
}
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.01/ace.js" type="text/javascript" charset="utf-8"></script>
  <script>
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/javascript");
    document.getElementById("editor").style.height = "120px";
  </script>
</body>

</html>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接