这是我进入公司遇到的第一个难题,项目里需要实现一个带语法高亮和代码提示在线页面编辑器的效果,就是那种左边代码右边界面的编辑器,页面编辑器作为一个以前我从来没有接触过的领域,这个需求对我来说是一个巨大的挑战,首先得确定使用哪个在线编辑器插件来实现这个功能,我在github,各种技术论坛找了一圈市面上口碑较好的编辑器大概有Monaco-editor,codemirror编辑器,AceEditor等等,我最终选择的是Monaco-editor编辑器原因就是他真的比其他的好用。先上最终实现的效果图:

Monaco编辑器 java monaco编辑器未定义_css


界面主要分为两块一块放html和js代码一块放css代码,有代码提示和语法高亮可以实时显示,接下来讲怎么实现的。

首先放上git地址 第一步先要安装Monaco-editor编辑器

我使用的npm的方式安装代码如下:

npm install monaco-editor

安装完了之后先新建一个index.html来放html代码

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    <link rel="stylesheet" href="./code.css">
</head>
<body>
  <div class="all">
<div class="main">
<div class="write">
<div id="container" ></div>
<div id="container1"></div>
</div>
<div class="live">
    <iframe id="preview" frameborder="0"></iframe>
</div>
</div>
<div class="bt">
    <button id="b1">获取代码</button>
    <button id="b2">运行代码</button>
    <button id="b3">清空代码</button>
    <!-- <button id="b4">实时显示</button> -->
</div></div>
<script src="node_modules/monaco-editor/min/vs/loader.js"></script>
<script src="./code.js">
   
</script>
</body>
</html>

引入下载的monaco-editor插件
css代码进行样式调整比较简陋

html,body{
    height: 100%;
    padding: 0px;
    margin: 0px;
    width: 1920px;
}
.main{
display: flex;
height: 100%;
overflow: hidden;

}
.live{
width: 1000px;
height: 100%;
background-color: #ffffff;
}
.bt{
position: absolute;
right: 1000px;
top: 0px;
}
.all{
position: relative;
height: 100%;
}
#container1
{
    width:920px;
    height:70%;
    border:1px solid grey;
}
#container
{
    width:920px;height:70%;
    border:1px solid grey;
}
button{
    background-color: black;
    color: white;
}
button:hover{
    background-color: blue;
}

最后是重头戏的js代码新建一个code.js

require.config({ paths: { 'vs': 'node_modules/monaco-editor/min/vs' } });
var editorArray = [];
var real = false
require(['vs/editor/editor.main'], function () {
  var editor = monaco.editor.create(document.getElementById('container'), {
    value: [
      '<div>',
      '</div>',
      '<script>',
      '\talert("Hello world!");',
      '<\/script>',
    ].join('\n'),
    language: 'html',
    theme: 'vs-dark',
    minimap: {
      enabled: false
    },
  });
  editorArray.push(editor)
});
require(['vs/editor/editor.main'], function () {
  var editor1 = monaco.editor.create(document.getElementById('container1'), {
    value: [
      'div{',
      'color: red;',
      '}'
    ].join('\n'),
    language: 'css',
  });
  editorArray.push(editor1)
});
document.getElementById("b1").addEventListener("click", function () {
  // 获取编辑器内容
  alert(editorArray[0].getValue() + '\n' + editorArray[1].getValue() + '\n');
});
document.getElementById("b3").addEventListener("click", function () {
  // 清空编辑器内容
  editorArray[0].setValue('')
  editorArray[1].setValue('')
  run()
});
document.getElementById("b2").addEventListener("click", function () {
  // 运行编辑器内容
  run()
});
function run() {
  var html = editorArray[0].getValue();
  var css = editorArray[1].getValue();

  var code = "<!DOCTYPE html>\n" +
    "<html lang=\"en\">\n" +
    "<head>\n" +
    "  <meta charset=\"UTF-8\">\n" +
    "  <title>Editor</title>\n" +
    "  <style>";
  code += "\n" + css;

  code +=
    "\n  </style>\n" +
    "</head>\n" +
    "<body>\n";
  code += "\n" + html;
  code +=
    "<\/body>\n" +
    "</html>";
  document.getElementById("preview").setAttribute("srcdoc", code);
}
//实时编辑
setTimeout(()=>{
  editorArray[0].onDidChangeModelContent((event) => {
    run();
   })
   editorArray[1].onDidChangeModelContent((event) => {
    run()})},1000)

首先使用require.config({ paths: { ‘vs’: ‘node_modules/monaco-editor/min/vs’ } });来用vs作为路径别名,避免路径过长的问题,然后就是根据id选择器来来在界面上使用create()方法初始化两个编辑器,并分别设置value(初始代码),language(语言),theme(主题)以及
minimap: {
enabled: false
},
隐藏右上角缩略图,还有其他配置项得大家自己去官网找了(它那官方文档我是真看不懂),然后就是使用编辑器实例getvalue()方法来获取编辑器中的值,为按钮分别绑定监听实现功能,右侧的界面部分我使用的是内联框架,将左边获取到的代码组合并且放入一个可以说新的界面,然后运行就行了,也可以onDidChangeModelContent()方法来监听编辑实现实时显示的效果,不过不知道为什么我直接输出编辑器数组里面是存在两个编辑器对象的,但我一旦使用下标取数组中的值就会返回undefined,这边我实在解决不了就使用了一个定时器来延迟获取数组中的值才行。
我只是初入使用了一下monaco-editor而本人也是刚入行不久的小白,有错误希望各位大佬指出,您的意见会成为我前进的动力。