最近,在搞一个自己的小软件,需要用到一个网页版的编辑器插件。在网上百度了一下,找到了一个不错的编辑器插件“CodeMirror”。下面是在其官网翻译的一段关于它的描述:
“CodeMirror 是用 JavaScript 语言实现的能在浏览器运行的多功能文本编辑器。它专门用于编辑代码,并带有许多语言模式和插件,可实现更高级的编辑功能。丰富的编程 API 和 CSS 主题系统可用于自定义 CodeMirror 以适应您的应用程序,并使用新功能对其进行扩展。”
以下是关于本文的段落描述:
如何获取 CodeMirror
关于 CodeMirror 的发布信息
关于 CodeMirror 的功能概要
关于 CodeMirror 的浏览器兼容性
本人写的参考页面代码
一、如何获取 CodeMirror
对于 CodeMirror 这个插件,在大版本上主要有 2 个:6.x 和 5.x 。目前,我使用的是 5.x 版本的,因为 6.x 在官网上没找到详细的使用说明文档。5.x 的网址如下:https://codemirror.net/5/ 。官网截图如下:

在官网的首页,上面有一个 demo ,可以根据选择框,自由切换功能效果。大家可以通过它,了解 CodeMirror 的功能特性。
点击上面的 Get the current version: 5.65.18 这个链接,就可以下载完整的 CodeMirror 5.x 版本完整程序包。

这是我之前下载到的,里面的文件大致如上图。
二、关于 CodeMirror 的发布信息
在知道如何获取软件包之后,我们来看看 CodeMirror 的发布情况


从上面看来,24年9月份还有更新,5.x 版本也是不错的选择。
三、关于 CodeMirror 的功能概要
其实 CodeMirror 功能挺多的,主要常用的大概以下几点:
1、支持100多种语言的代码着色,具体支持哪些,可以看 下载下来的压缩包中的 mode 文件夹。
2、强大的多语言混合模式。比如,编辑 html 代码,里面会混杂 css ,js ,html 三种处理。编辑器能很好配合。
3、提供丰富的主题样式支持,具体支持哪些,可以看 下载下来的压缩包中的 theme 文件夹。当然,你也可以写属于自己的主题样式。
4、具有完善的键位映射功能。支持各种快捷键,也可以自己编程,配置键位映射。
5、具有代码自动提示功能,需自己编程配置。
6、有丰富的插件支持,比如:括号匹配,选择行高亮等等。也可以自己写插件。
7、其它更多信息,请参考说明文档。
四、关于 CodeMirror 的浏览器兼容性
CodeMirror 5.x 版本,支持以下浏览器的桌面版本,在标准模式下(建议使用 HTML5 <!doctype html>):
Firefox 版本 4 及更高版本
Chrome 任何版本
Safari 版本 5.2 及更高版本
IE/Edge 版本 8 及更高版本
Opera 版本 9 及更高版本
对现代移动浏览器的支持是实验性的。最新版本的 iOS 浏览器和 Android 上的 Chrome 应该运行良好。
五、本人写的参考页面代码
在学习如何使用这个编辑器时,本人自己写了一个测试页面,大家可以参考下。由于我这里只需要编写 SQL 语句,所以,我只使用了 sql 模式,仅供参考。
1、页面截图


2、源代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- codemirror 核心 样式 css -->
<link rel="stylesheet" type="text/css" href="codemirror-5.65.17/lib/codemirror.css" />
<!-- codemirror 2 个额外的主题样式 css -->
<link rel="stylesheet" type="text/css" href="codemirror-5.65.17/theme/idea.css" />
<link rel="stylesheet" type="text/css" href="codemirror-5.65.17/theme/material-palenight.css" />
<!-- codemirror 滚动条插件 样式 css -->
<link rel="stylesheet" href="codemirror-5.65.17/addon/scroll/simplescrollbars.css"/>
<!-- codemirror 核心 js -->
<script src="codemirror-5.65.17/lib/codemirror.js"></script>
<!-- codemirror 模式 js (sql语言) -->
<script src="codemirror-5.65.17/mode/sql/sql.js"></script>
<!-- codemirror 3 个 扩展插件 js (选中的行、括号匹配,滚动条) -->
<script src="codemirror-5.65.17/addon/selection/active-line.js"></script>
<script src="codemirror-5.65.17/addon/edit/matchbrackets.js"></script>
<script src="codemirror-5.65.17/addon/scroll/simplescrollbars.js"></script>
</head>
<body>
<h1>测试在线编辑器</h1>
<div>
<label>要映射的Sql语句</label>
<textarea id="myArea">/* 请输入数据库查询语句,比如:select * from my_table */</textarea>
<div class="invalid-feedback">请填写sql语句</div>
</div>
<div>
<button id="myBtn" onclick="getText()">提取文本</button>
<button id="myBtn2" onclick="clearText()">清空内容</button>
<button id="myBtn3" onclick="lockEditor()">锁定编辑器</button>
<button id="myBtn4" onclick="lockEditorAndClear()">锁定编辑器并清空内容</button>
<button id="myBtn5" onclick="unlockEditor()">解锁编辑器</button>
<button id="myBtn6" onclick="saveScriptStr()">保存脚本</button>
<button id="myBtn7" onclick="loadScriptstr()">加载脚本</button>
<select id="themeBtn" onchange="changeTheme()">
<option>default</option>
<option>idea</option>
<option>material-palenight</option>
</select>
</div>
<script>
//处理
var myTextarea = document.getElementById('myArea');
var editor = CodeMirror.fromTextArea(myTextarea, {
value: myTextarea.value,
lineNumbers: true,
styleActiveLine: true,
matchBrackets: true,
theme: 'default',
mode: 'sql',
scrollbarStyle: "simple",
/*lineNumberFormatter:function(lineno){
return lineno + ' >>';
}*/
});
</script>
<script>
/**
* 获取原始的字符串内容
*/
function getOriText(){
return editor.getValue();
}
/**
* 获取过滤注释后的脚本字符串
*/
function getText(){
//首先,获取内容,内容可能是多行的。)
const oriText = editor.getValue();
//替换 星号 注释
let tmpText = oriText.replace(/\/\*(.|\n)+?\*\//ig, '');
//替换 单行 注释
tmpText = tmpText.replace(/[\-]{2}[ ]?.*([\n]+|$)/mg, '');
//替换换行符
tmpText = tmpText.replace(/[\r\n]+/mg, ' ');
//输出
alert(tmpText);
}
/**
* 清空编辑器的内容。因为value 和 option配置中 偶发 不同步。所以要设置2次
*/
function clearText(){
editor.setValue('');
editor.setOption('value', '');
}
/**
* 主题css切换。
*/
function changeTheme(){
editor.setOption("theme", document.getElementById('themeBtn').value);
}
/**
* 锁定编辑器
*/
function lockEditor(){
editor.setOption("readOnly", 'nocursor');
}
/**
* 锁定编辑器,并且清空内容
*/
function lockEditorAndClear(){
clearText();
editor.setOption("readOnly", 'nocursor');
}
/**
* 解锁编辑器
*/
function unlockEditor(){
editor.setOption("value", "/* 请输入数据库查询语句,比如:select * from my_table */");
editor.setOption("readOnly", false);
}
/**
* 获取字符串的字节长度
*/
function getByteLengthOfStr(str){
let re = 0;
//只处理字符串
if(typeof str === 'string'){
re = new Blob([str]).size;
}else{
re = -1;
}
return re;
}
/**
* 保存编辑器中的脚本
*/
function saveScriptStr(){
let choose = confirm('如果保存脚本,则会覆盖原有保存的内容,确认保存?');
if(choose){
let oriStr = getOriText();
let size = getByteLengthOfStr(oriStr);
if(size<0) {
alert('计算字符串长度出错,获取的内容异常');
return false;
}
if(size===0){
alert('获取的内容为空,不执行内容保存操作');
return false;
}
if(size>5000000){
alert('获取的内容长度超过5MB,无法保存');
return false;
}
//开始执行保存
window.localStorage.setItem('MySqlScript', oriStr);
alert('保存成功!');
}
}
/**
* 加载已经保存的脚本
*/
function loadScriptstr(){
let choose = confirm('如果加载已经存储的内容,可能会覆盖当前内容,确认加载?');
if(choose){
//提取
let str = window.localStorage.getItem('MySqlScript');
if(typeof str ==="string"){
editor.setValue(str);
}else{
alert('加载不到可用的字符串数据');
}
}
}
</script>
</body>
</html>