CodeMirror 使用教程
CodeMirror 是一个功能强大、高度可定制的代码编辑器组件,专为网页应用设计,它被广泛应用于在线代码编辑器、IDE、教程网站等场景。

本教程将带你一步步了解如何使用 CodeMirror。
目录
-
- 引入文件
- 创建 HTML 结构
- 初始化编辑器
- 完整示例
- 关键 API 解析
-
- 配置选项
- 获取和设置值
- 事件监听
- 模式
- 主题
-
(图片来源网络,侵删)- 代码提示/自动补全
- 代码折叠
- 行号显示
- 括号匹配
- 搜索与替换
- 只读模式
-
- 需求分析
- 实现步骤
- 完整代码
第一部分:快速入门 - 5分钟搭建你的第一个代码编辑器
引入文件
你需要将 CodeMirror 的 CSS 和 JavaScript 文件引入到你的 HTML 页面中,你可以通过 CDN 或下载本地文件的方式引入。
使用 CDN (推荐):

<!-- 引入 CodeMirror 的 CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css"> <!-- 引入主题 CSS (这里以 monokai 主题为例) --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/monokai.min.css"> <!-- 引入 CodeMirror 的 JS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script> <!-- 引入你需要的语言模式 JS (这里以 JavaScript 为例) --> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/javascript/javascript.min.js"></script>
本地文件: 从 CodeMirror 官网 下载最新版本,然后将相应的 CSS 和 JS 文件放入你的项目中。
创建 HTML 结构
在 <body> 标签中,创建一个 <textarea> 元素,CodeMirror 会将这个 <textarea> 替换成功能丰富的代码编辑器。
<textarea id="myEditor"></textarea>
初始化编辑器
在 <script> 标签中,使用 JavaScript 初始化 CodeMirror。
const editor = CodeMirror.fromTextArea(document.getElementById('myEditor'), {
lineNumbers: true, // 显示行号
mode: 'javascript', // 设置语言模式
theme: 'monokai' // 设置主题
});
完整示例
将以上三部分组合起来,你就可以看到一个可以工作的 JavaScript 代码编辑器了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">CodeMirror 快速入门</title>
<!-- 引入 CodeMirror 的 CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css">
<!-- 引入主题 CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/monokai.min.css">
<style>
/* 给编辑器容器设置一个高度,否则可能不可见 */
.CodeMirror {
height: 400px;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<h1>我的第一个 CodeMirror 编辑器</h1>
<textarea id="myEditor">// 输入一些 JavaScript 代码
function helloWorld() {
console.log("Hello, CodeMirror!");
}
helloWorld();</textarea>
<!-- 引入 CodeMirror 的 JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script>
<!-- 引入 JavaScript 语言模式 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/javascript/javascript.min.js"></script>
<script>
// 初始化编辑器
const editor = CodeMirror.fromTextArea(document.getElementById('myEditor'), {
lineNumbers: true, // 显示行号
mode: 'javascript', // 语言模式为 JavaScript
theme: 'monokai', // 使用 monokai 主题
indentUnit: 2, // 缩进单位为2个空格
lineWrapping: true // 自动换行
});
</script>
</body>
</html>
关键 API 解析
CodeMirror.fromTextArea(textareaElement, config): 这是初始化编辑器的核心方法,它接收一个<textarea>DOM 元素和一个配置对象。lineNumbers: true: 在编辑器左侧显示行号。mode: 'javascript': 指定编辑器的语言模式,CodeMirror 会根据此模式进行语法高亮,你需要引入对应的模式文件。theme: 'monokai': 指定编辑器的视觉主题,你需要引入对应的主题文件。
第二部分:核心功能详解
配置选项
在初始化时,通过配置对象可以精细地控制编辑器的行为。
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
lineNumbers |
boolean |
false |
是否显示行号。 |
mode |
string |
null |
语言模式,如 "javascript", "python", "css"。 |
theme |
string |
"default" |
主题名称,如 "monokai", "material", "one-dark"。 |
indentUnit |
number |
2 |
缩进的空格数。 |
indentWithTabs |
boolean |
false |
是否使用制表符进行缩进。 |
lineWrapping |
boolean |
false |
是否自动换行。 |
smartIndent |
boolean |
true |
是否智能缩进(新行根据上一行内容自动缩进)。 |
tabSize |
number |
4 |
制表符的宽度(空格数)。 |
readOnly |
boolean |
false |
是否为只读模式。 |
autofocus |
boolean |
false |
页面加载后是否自动聚焦到编辑器。 |
获取和设置值
编辑器实例提供了获取和设置内容的方法。
-
获取值
const currentValue = editor.getValue(); // 获取编辑器的全部文本内容 console.log(currentValue);
-
设置值
editor.setValue("let newCode = 'Hello, world!';\nconsole.log(newCode);"); -
获取光标位置
const cursorPos = editor.getCursor(); // 返回 { line: number, ch: number } console.log(`当前光标在第 ${cursorPos.line} 行,第 ${cursorPos.ch} 个字符`); -
设置光标位置
editor.setCursor({ line: 3, ch: 0 }); // 将光标移动到第4行开头
事件监听
编辑器在发生特定事件时会触发回调函数。
-
"change": 编辑器内容发生变化时触发(非常常用)。editor.on("change", function(instance, changeObj) { // changeObj 描述了变化 // { from: {line, ch}, to: {line, ch}, removed: [...], text: [...] } console.log("编辑器内容已更新!"); // 可以在这里执行保存、验证等操作 }); -
"cursorActivity": 光标或选中区域发生变化时触发。editor.on("cursorActivity", function() { console.log("光标移动了或选中区域改变了。"); });
模式
模式是 CodeMirror 的核心,它决定了如何对代码进行语法高亮,CodeMirror 支持数十种语言模式。
- 如何使用: 在引入 JS 文件后,在
config中设置mode即可。<!-- 引入 Python 模式文件 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/python/python.min.js"></script>
const pythonEditor = CodeMirror.fromTextArea(document.getElementById('pythonEditor'), { mode: 'python', lineNumbers: true });
主题
主题决定了编辑器的颜色方案和外观。
- 如何使用: 引入 CSS 文件后,在
config中设置theme即可。<!-- 引入 Material 主题 --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/material.min.css">
const materialEditor = CodeMirror.fromTextArea(document.getElementById('materialEditor'), { theme: 'material', // 使用 material 主题 lineNumbers: true });
第三部分:进阶功能
代码提示/自动补全
CodeMirror 本身不提供自动补全功能,但它与一个名为 CodeMirror-addon-hint 的官方插件无缝集成。
步骤:
-
引入文件
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/hint/show-hint.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/hint/show-hint.min.css">
-
配置编辑器
const editor = CodeMirror.fromTextArea(myTextarea, { // ... 其他配置 extraKeys: { "Ctrl-Space": "autocomplete" // 绑定 Ctrl+Space 触发自动补全 } }); // 注册提示源 CodeMirror.registerHelper("hint", "javascript", function(editor) { // 这里可以写更复杂的逻辑,从你的项目中获取变量/函数列表 const word = editor.getTokenAt(editor.getCursor()).string; const list = ["function", "var", "let", "const", "console", "log"]; return { list: list.filter(item => item.startsWith(word)), from: CodeMirror.Pos(editor.getCursor().line, editor.getCursor().ch - word.length), to: CodeMirror.Pos(editor.getCursor().line, editor.getCursor().ch) }; }); // 当按下触发键时,显示提示 editor.on("inputRead", function() { if (editor.state.completionActive) return; CodeMirror.showHint(editor, CodeMirror.hint.javascript); });
代码折叠
通过 foldGutter 插件实现。
-
引入文件
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldcode.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldgutter.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldgutter.min.css">
-
配置编辑器
const editor = CodeMirror.fromTextArea(myTextarea, { // ... 其他配置 lineNumbers: true, foldGutter: true, // 开启折叠 gutter extraKeys: { "Ctrl-Q": "toggleFold" // 绑定 Ctrl-Q 切换折叠 } });
行号显示
非常简单,只需在配置中设置 lineNumbers: true。
括号匹配
默认开启,无需额外配置,它会高亮显示匹配的括号。
搜索与替换
通过 search 插件实现。
-
引入文件
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/search/search.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/search/searchcursor.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/dialog/dialog.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/dialog/dialog.min.css">
-
配置编辑器
const editor = CodeMirror.fromTextArea(myTextarea, { // ... 其他配置 extraKeys: { "Ctrl-F": "find", // 查找 "F3": "findNext", // 查找下一个 "Shift-F3": "findPrev", // 查找上一个 "Ctrl-H": "replace", // 替换 "Alt-F": "findPersistent" // 持久查找(界面更好看) } });
只读模式
只需在配置中设置 readOnly: true。
第四部分:实战案例 - 构建一个简单的在线代码编辑器
我们将创建一个包含编辑器、代码高亮、主题切换和运行按钮的简单在线代码编辑器。
需求:
- 一个代码编辑器,默认内容为 JavaScript 代码。
- 可以切换编辑器主题(如
default和monokai)。 - 点击 "运行" 按钮,在控制台打印代码的执行结果。
实现步骤:
-
HTML 结构
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>简易在线代码编辑器</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/monokai.min.css"> <style> body { font-family: sans-serif; } #editor-container { height: 400px; border: 1px solid #ccc; } #controls { margin: 10px 0; } select, button { padding: 5px; } #output { margin-top: 10px; padding: 10px; background: #f4f4f4; border: 1px solid #ddd; min-height: 50px; } </style> </head> <body> <h1>简易在线代码编辑器</h1> <div id="controls"> <label for="theme-select">选择主题: </label> <select id="theme-select"> <option value="default">Default</option> <option value="monokai">Monokai</option> </select> <button id="run-btn">运行代码</button> </div> <div id="editor-container"> <textarea id="code-editor">// 在这里输入你的 JavaScript 代码 function greet(name) { return `Hello, ${name}!`; }
console.log(greet("CodeMirror"));
<h3>输出:</h3>
<pre id="output"></pre>
<!-- JS 文件 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/javascript/javascript.min.js"></script>
<script src="app.js"></script>
</body>
</html>
```
-
JavaScript 逻辑 (
app.js)document.addEventListener('DOMContentLoaded', () => { // 1. 初始化编辑器 const editor = CodeMirror.fromTextArea(document.getElementById('code-editor'), { mode: 'javascript', theme: 'default', lineNumbers: true, indentUnit: 2, lineWrapping: true }); // 2. 获取 DOM 元素 const themeSelect = document.getElementById('theme-select'); const runButton = document.getElementById('run-btn'); const outputElement = document.getElementById('output'); // 3. 主题切换功能 themeSelect.addEventListener('change', (e) => { editor.setOption('theme', e.target.value); }); // 4. 运行代码功能 runButton.addEventListener('click', () => { // 清空之前的输出 outputElement.textContent = ''; // 重定向 console.log const originalLog = console.log; const logs = []; console.log = (...args) => { logs.push(args.map(arg => String(arg)).join(' ')); }; try { // 使用 Function 构造函数安全地执行代码 const userCode = editor.getValue(); const func = new Function(userCode); func(); // 执行用户代码 // 显示捕获到的日志 if (logs.length > 0) { outputElement.textContent = logs.join('\n'); } else { outputElement.textContent = '代码执行完成,无输出。'; } } catch (error) { // 捕获并显示错误 outputElement.textContent = `错误: ${error.message}`; } finally { // 恢复原始的 console.log console.log = originalLog; } }); });
第五部分:总结与最佳实践
- 按需引入: 不要一次性引入所有插件和模式,只引入你项目需要的,这可以显著减少页面加载体积。
- 性能考虑: 对于非常大的文件,可以考虑启用
viewportMargin选项来优化渲染性能。 - 版本选择: CodeMirror 5.x 和 6.x 是两个完全不同的版本,目前绝大多数教程和插件都是基于 5.x 的,除非你有特殊需求,否则建议使用稳定且生态丰富的 x 版本。
- 事件驱动: 充分利用
"change"事件来监听用户输入,实现实时保存、语法检查等功能。 - 配置隔离: 如果一个页面有多个编辑器,最好为它们创建不同的配置对象,以避免样式和行为上的冲突。
希望这份详细的教程能帮助你顺利上手 CodeMirror!
