摩纳哥编辑器可动态调整大小

3,279 阅读5分钟

我一直在寻找关于在整个互联网上使用Monaco Editor的字段时是否可以模仿 html 标签 textarea 的大小调整的讨论,但我找不到回答我的问题的人。

我在React应用程序中使用monaco-editor npm 包。你知道这是否容易实现吗?****

先感谢您!

解决方案
使用纯 css 我选择了目标 html 元素并添加了这些属性:

div {
  resize: vertical;
  overflow: auto;
}

javascript节点.js反应摩纳哥编辑

分享

改进这个问题

跟随

于 2019 年 10 月 7 日 17:54编辑

用户头像

桑温·加万德

6,62688 金徽章4545枚银质徽章6060枚铜牌

2017 年 10 月 30 日 14:29 提问

用户头像

埃琳娜·赫里斯托娃

44111 个金徽章77个银质徽章1616枚铜牌

  • 1

    我建议您在答案部分回答您的问题,而不仅仅是编辑答案,然后接受它。会更好。 

    – 萨特南桑杜

     2019 年 1 月 1 日 20:16 

  • 这让我非常头疼。使用monaco-react需要 5 分钟,默认情况下它是响应式的。 

    – 帕尔姆

     2020 年 8 月 19 日 22:09

添加评论

6 个答案

排序:

                                              最高分(默认)                                                                   修改日期(最新的在前)                                                                   创建日期(最早的在前)                              

48

TL;DR: 添加automaticLayout: true到编辑器的配置中。

荷兰;公关:

Monaco 有一个内置的自动调整大小到父容器的功能:

    createEditorWithAutoResize(){
      this.editor = monaco.editor.create(
            this.editorDiv.current, {
            value: "var x = 0;",
            language: 'javascript',
            automaticLayout: true // <<== the important part
       }
      );
    }
    componentDidMount(){this.createEditorWithAutoResize();}
    constructor(props){super(props); this.editorDiv = React.createRef();}
    render(){return <div ref={this.editorDiv} className="editor" ></div>}

以及编辑器的 CSS(它避免了第一次以 10px 的高度渲染编辑器):

    .editor{
     height: 100%;
    } 

第一次测试:  v0.10.1,最后一次测试:  v0.32.1

注意:  < v0.20.0:该机制不会监听其容器大小的变化,而是轮询它们

@nrayburn-tech(摩纳哥编辑的贡献者):0.20 版对所有浏览器都使用 MutationObserver。0.21 及更高版本在支持的浏览器上使用 ResizeObserver,否则,它使用轮询作为后备。

分享

改进这个答案

跟随

2 月 25 日 16:36编辑

于 2017 年 11 月 7 日 17:24 回答

用户头像

大卫一世萨穆迪奥

1,8011414枚银质徽章1717枚铜牌

  • 3

    如果您需要性能,不建议这样做。github.com/Microsoft/m… 

    – 阿蒂尔坎

     2019 年 1 月 10 日 2:25

  • 你读过笔记吗?投票与倾听?官方文档参考? 

    – 大卫一世萨穆迪奥

     2019 年 6 月 26 日 20:47

  • 奇怪的。当我设置automaticLayouttrue并将编辑器设置height为 时100%,编辑器不会增长/调整大小。如您所述,如果我不设置height, if 第一次将编辑器呈现为 ~ 10px,但仍然不会调整大小。 

    – 特雷弗

     2 月 24 日 19:26

  • 你用的是什么版本?我记得 0.2x 版本有一个问题。在此处添加选项时它可以正常工作:microsoft.github.io/monaco-edit… 

    – 大卫一世萨穆迪奥

     2 月 25 日 16:36

添加评论

13

如果您对编辑器有参考,您可以调用 editor.layout() 一些调整大小事件。例如,在调整窗口大小时:

window.onresize = function (){
    editor.layout();
};

分享

改进这个答案

跟随

于 2020 年 8 月 2 日 20:57编辑

用户头像

社区机器人

111 个银色徽章

于 2017 年 11 月 28 日 22:26 回答

用户头像

简单的

2,70722个金徽章1313枚银质徽章1818枚铜牌

添加评论

3

这是个老问题,但是用react-resize-detector解决了这个问题

基于ResizeObserver它完全符合需要(检查浏览器兼容性

组件示例:

import React, { Component } from 'react';
import ReactResizeDetector from 'react-resize-detector';
import * as monaco from 'monaco-editor';

class Editor extends Component {
    constructor(props) {
        super(props)

        this.state = {
            width: 0,
            height: 0,
        }
        this.editor_div = React.createRef()

        this.handle_rezise = this.handle_rezise.bind(this);
    }

    componentDidMount() {
        const editor_model = monaco.editor.createModel('', 'sql');
        this.monaco_editor = monaco.editor.create(this.editor_div.current, this.props.editorOptions);
        this.monaco_editor.setModel(editor_model);
    }

    componentWillUnmount() {
        this.monaco_editor && this.monaco_editor.dispose();
    }

    handle_rezise(width, height) {
        this.monaco_editor.layout({ height, width });
    }

    render() {
        return(
            <div 
                className="editor-container"
                style={{ height: '100%' }}>
                <ReactResizeDetector
                    handleWidth
                    handleHeight
                    onResize={ this.handle_rezise }
                    refreshMode="debounce"
                    refreshRate={100} />
                <div 
                    className="editor"
                    ref={ this.editor_div }
                    style={{ height: '100%' }} />
            </div>
        )
    }
}

export default Editor;

希望有帮助

分享

改进这个答案

跟随

于 2019 年 4 月 18 日 10:46 回答

用户头像

Naej56

4111 个青铜徽章

添加评论

2

在我的情况下,我使用的是确切的 CSS,但是虽然 automaticLayout: true 有效,但我发现过度杀伤(似乎汇集了 DOM 100ms 间隔,并且我在文档中打开了几个编辑器。所以我最终手动实现它:

以防万一,我的需求有所不同:我希望用户以标准方式调整容器的大小,并且在库和性能方面便宜(在代码和性能方面)。这就是我所做的:

CSS容器:resize: vertical; overflow: auto

这个js:

function installResizeWatcher(el, fn, interval){
  let offset = {width: el.offsetWidth, height: el.offsetHeight}
  setInterval(()=>{
    let newOffset = {width: el.offsetWidth, height: el.offsetHeight}
    if(offset.height!=newOffset.height||offset.width!=newOffset.width){
      offset = newOffset
      fn()
    }
  }, interval)
}
  const typeScriptCodeContainer = document.getElementById('typeScriptCodeContainer')
  typeScriptCodeEditor = monaco.editor.create(typeScriptCodeContainer, Object.assign(editorOptions, {value: example.codeValue}))
  installResizeWatcher(typeScriptCodeContainer, typeScriptCodeEditor.layout.bind(typeScriptCodeEditor), 2000)

是的,间隔 2 秒,并确保它只注册一次。我看到摩纳哥的自动重新布局在 100ms 上有一个调整大小间隔 - 恕我直言,这太多了。

看看它的实际效果:https ://typescript-api-playground.glitch.me/?example=2

分享

改进这个答案

跟随

于 2018 年 6 月 21 日 22:19 回答

用户头像

癌症贝罗

6,22611 个金徽章3030个银质徽章2121枚铜牌

添加评论

0

对于后代,我得到的解决方案是设置automaticLayout: false,以便我可以在调整大小事件侦听器中执行所有布局。

const placeholder = document.getElementById('placeholder')

const editor = monaco.editor.create(placeholder, {
  value: '// hello world',
  language: 'javascript',
  automaticLayout: false // or remove, it defaults to false
})

// we need the parent of the editor
const parent = placeholder.parentElement

window.addEventListener('resize', () => {
  // make editor as small as possible
  editor.layout({ width: 0, height: 0 })

  // wait for next frame to ensure last layout finished
  window.requestAnimationFrame(() => {
    // get the parent dimensions and re-layout the editor
    const rect = parent.getBoundingClientRect()
    editor.layout({ width: rect.width, height: rect.height })
  })
})

通过首先将编辑器布局减少到 0,我们可以安全地查询父元素的尺寸,而不会影响其大小。然后我们可以将编辑器与新的父维度匹配。由于这发生在单个帧上,因此不应出现闪烁或延迟。

分享

改进这个答案

跟随

于 2021 年 11 月 26 日 6:56 回答

用户头像

苏维特

83.4k4343枚金徽章174174枚银质徽章236236枚青铜徽章

添加评论

0

对于任何在基本网络应用程序(html、css、javascript)中遇到此问题的人,我已经找到了解决我遇到的调整大小问题的方法。

我在一个可调整大小的 flex 容器中安装了 monaco 编辑器。它只会增加宽度,而不是缩小它,并且垂直调整大小似乎不能开箱即用。

如果您使用 monaco 配置 "automaticLayout: true" 和以下 CSS,它似乎会按预期调整大小:

.monaco-editor { 位置:绝对!重要;}

我尝试了最大宽度 99% 的技巧,但是当增加页面边缘附近的宽度时,它会导致延迟效果。