首页 > 解决方案 > 根据其中字符的长度设置ace编辑器实例的宽度

问题描述

我正在开发使用 contenteditable 属性创建自定义富文本编辑器的项目。在这个富文本编辑器中,我想插入单行 ace 编辑器实例,其宽度将根据其中的字符数设置。

为了将 ace 编辑器实例限制为单行,我处理了“Enter”键事件,它不允许 ace 实例插入新行。

var editor = ace.edit(script_editor);
editor.commands.on("exec", function (e) {
editor.container.querySelector(".ace_content").style.transform = "none";
 if (e.args && e.args.charCodeAt(0) == 10) {
  e.preventDefault();
  e.stopPropagation();
  console.log("vdgscript-mode.js")
 }
}); 

现在,我面临的问题是我希望 ace 实例宽度根据其中的字符数进行调整,而不是全宽。

为此,我正在使用画布对象并计算文本的宽度。但是这段代码的问题是,它在每次按键时都给了我预期的宽度,但是 ace 编辑器的 css left 属性不会保持“0px”,这使得 ace 编辑器实例中的文本隐藏在左侧。

设置宽度的代码如下:

var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.font = "15px sans-serif";
var width = ctx.measureText(code).width;
editor.container.style.width = (width + 3) + "px";

实际结果:有效的 XHTML

预期结果:有效的 XHTML

下图中的黑色是我输入数组的 ace 实例。

标签: javascriptcontenteditableace-editor

解决方案


您可以使用类似于 cloud9 中的树重命名编辑器使用的方法https://github.com/c9/core/blob/master/plugins/node_modules/ace_tree/lib/ace_tree/edit.js

<style>
#inlineEditor {
  display: inline-block;
  vertical-align: middle;
}
</style>
<div>inline editor <span id=inlineEditor>txt</span></div>
<script src=https://ajaxorg.github.io/ace-builds/src-noconflict/ace.js>
</script>

<script>

var inlineEditor = ace.edit("inlineEditor", {
  maxLines: 1,
  showGutter: false,
  showPrintMargin: false,
  theme: "ace/theme/solarized_light",
})


// make cursor movement nicer for
inlineEditor.renderer.screenToTextCoordinates = function(x, y) {
    var pos = this.pixelToScreenCoordinates(x, y);
    return this.session.screenToDocumentPosition(
        Math.min(this.session.getScreenLength() - 1, Math.max(pos.row, 0)),
        Math.max(pos.column, 0)
    );
};
        
inlineEditor.renderer.on("beforeRender", updateSize)
function updateSize(e, renderer) {
  var text = renderer.session.getLine(0);
  var chars = renderer.session.$getStringScreenWidth(text)[0];
   
  var width = Math.max(chars, 2) * renderer.characterWidth // text size
    + 2 * renderer.$padding // padding
    + 2 // little extra for the cursor
    + 0 // add border width if needed
   
  // update container size
  renderer.container.style.width = width + "px";
  // update computed size stored by the editor
  renderer.onResize(false, 0, width, renderer.$size.height);
}
updateSize(null, inlineEditor.renderer)
</script>


推荐阅读