在线代码教程网站带来了对实时代码编辑器的需求。这些编辑器的目的是描绘代码片段或为代码片段添加一些增强功能。在线代码编辑器也作为远程工作空间和团队工作工具。 有几个网站使用代码编辑器,其中最受欢迎的是codepen
。还有其他值得一提的,如w3school
和js fiddle
。
在这篇文章中,我们将围绕CodeMirror展开。CodeMirror就是我们所说的用JavaScript实现的flexible
文本编辑器,用于浏览器编辑代码。我们将讨论codemirror的几种语言模式和用于更高级的编辑功能的附加组件。
它是Mozilla的Firefox、IOS的Safari和Google的Chrome的开发工具中使用的编辑器。本教程将指导你如何使用code mirror独特的API建立你的代码编辑器。
目标
在本指南中,我们将使用codemirror的API建立一个代码编辑器。在本教程结束时,我们将有一个功能性的代码编辑器来运行HTML
、CSS
和JavaScript
。
它还将具有诸如代码自动完成、快速格式等功能。通过split.js,我们的编辑器将有一个分割的、可调整的屏幕,在编辑器和iframe之间显示。
开始使用
为了开始,我们需要导入codemirror的JavaScript和CSS文件。我们下载了这些文件,并存储在这里的GitHub仓库中。为了使事情更简单,我们建议将这些文件下载到你的本地存储。
创建导航条
我们将创建一个简单的前端,其中包括运行等按钮和一个包含我们的格式和评论功能的下拉列表。为了实现这一点,我们将利用bootstrap 5
,这将有助于页面的风格化。
为了开始,我们初始化我们的HTML模板,添加我们的个人CSS,bootstrap JS,以及使用内容交付网络(CDN)的CSS文件。
<html lang="en">
<head>
<title>Code-Editor</title>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
/>
</head>
<body></body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</html>
接下来,我们将创建一个包含上述功能的导航条。我们将首先在我们的正文部分添加一个nav
标签,然后是一个div。
之后,我们将在div中添加一个无序列表标签(ul
),同时在run
中添加一个有序列表标签(li
)。这就是导航条的基本标签。
导航条的理想设计如下所示。
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<ul class="nav navbar-nav">
<li><a class="btn" id="run-btn">Run</a></li>
<li class="nav-item dropdown">
<a class="btn dropdown-toggle" type="button" data-toggle="dropdown"
>Dropdown Example <span class="caret"></span
></a>
<ul class="dropdown-menu">
<li><a href="javascript:autoFormatSelection()">Format</a></li>
<li><a href="javascript:commentSelection(true)">Comment</a></li>
<li><a href="javascript:commentSelection(false)">Uncomment</a></li>
</ul>
</li>
</ul>
</div>
</nav>
如果实施得当,我们应该看到我们的导航条如下图所示。
添加文本编辑器和iframe显示
这一部分涉及添加一个并排的编辑器和iframe显示。我们将在split.js的帮助下,使用一个可调整的调整器将它们分开。我们将添加codemirrors的CSS和JS文件,split.js文件与内容交付网络。
<link rel="stylesheet" href="codemirror.css" />
<script src="codemirror.js"></script>
<script src="https://unpkg.com/split.js/dist/split.min.js"></script>
注意:我们对Codemirror的CSS做了一些轻微的修改,以获得我们想要的结果。
然后我们创建一个容器div
,接着在容器内创建两个独立的div
。其中一个div
是用于编辑器,另一个用于iframe显示。对于分割功能,我们将为其创建一个脚本标签。
下面是一个实现的例子。
<div class="editor">
<div id="resizeMe" class="code a">
<div class="html-code"></div>
</div>
<div class="code pa">
<iframe id="preview-window"></iframe>
</div>
</div>
<script>
Split([".a", ".pa"]);
</script>
.a
和 是编辑器和iframe显示的类名。.pa
总的来说,我们应该有如下所示的布局。
添加主要的编辑器功能
接下来,我们将使编辑器兼容JavaScript、CSS和HTML。我们还将添加自动完成和格式化功能。
让我们开始吧。我们需要将Javascript
、HTML
和CSS
的JavaScript文件导入我们的代码,如下图所示。
<script src="xml.js"></script>
<script src="javascript.js"></script>
<script src="css.js"></script>
<script src="htmlmixed.js"></script>
我们将创建一个脚本标签,这是项目的基本部分。根据文档,我们要使用.getValue()
,而不是.value()
。
JavaScript的代码如下所示。
var htmlEditor = CodeMirror(
document.querySelector(".editor .code .html-code"),
{
mode: "htmlmixed",
tabSize: 4,
lineNumbers: true,
extraKeys: { "Ctrl-Space": "autocomplete" },
}
);
CodeMirror.commands["selectAll"](htmlEditor);
function getSelectRange() {
return { from: htmlEditor.getCursor(true), to: htmlEditor.getCursor(false) };
}
function autoFormatSelection() {
var range = getSelectRange();
htmlEditor.autoFormatRange(range.from, range.to);
}
function commentSelection(isComment) {
var range = getSelectRange(),
selStart = htmlEditor.getCursor("start");
htmlEditor.commentRange(isComment, range.from, range.to);
htmlEditor.setSelection(selStart, htmlEditor.getCursor("end"));
}
document.querySelector("#run-btn").addEventListener("click", function () {
let htmlCode = htmlEditor.getValue();
let previewWindow =
document.querySelector("#preview-window").contentWindow.document;
previewWindow.open();
previewWindow.write(htmlCode);
previewWindow.close();
});
.querySelector()
给出文档中第一个匹配给定CSS选择器的元素。
对于auto-compelete
功能、comment
和format
功能,我们将导入它们各自的JavaScript和CSS文件,如下所示。
<link rel="stylesheet" href="show-hint.css" />
<script src="formatting.js"></script>
<script src="show-hint.js"></script>
<script src="xml-hint.js"></script>
<script src="html-hint.js"></script>
文件中的最终代码应该是这样的。
<html lang="en">
<head>
<title>Code-Editor</title>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="codemirror.css" />
<link rel="stylesheet" href="show-hint.css" />
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
/>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<ul class="nav navbar-nav">
<li><a class="btn" id="run-btn">Run</a></li>
<li class="nav-item dropdown">
<a class="btn dropdown-toggle" type="button" data-toggle="dropdown"
>Options <span class="caret"></span
></a>
<ul class="dropdown-menu">
<li><a href="javascript:autoFormatSelection()">Format</a></li>
<li><a href="javascript:commentSelection(true)">Comment</a></li>
<li>
<a href="javascript:commentSelection(false)">Uncomment</a>
</li>
</ul>
</li>
</ul>
</div>
</nav>
<div class="editor">
<div id="resizeMe" class="code a">
<div class="html-code"></div>
</div>
<div class="code pa">
<iframe id="preview-window"></iframe>
</div>
</div>
</body>
<script src="codemirror.js"></script>
<script src="formatting.js"></script>
<script src="show-hint.js"></script>
<script src="xml-hint.js"></script>
<script src="html-hint.js"></script>
<script src="xml.js"></script>
<script src="javascript.js"></script>
<script src="css.js"></script>
<script src="htmlmixed.js"></script>
<script src="https://unpkg.com/split.js/dist/split.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script>
Split([".a", ".pa"]);
var htmlEditor = CodeMirror(
document.querySelector(".editor .code .html-code"),
{
mode: "htmlmixed",
tabSize: 4,
lineNumbers: true,
extraKeys: { "Ctrl-Space": "autocomplete" },
}
);
CodeMirror.commands["selectAll"](htmlEditor);
function getSelectedRange() {
return {
from: htmlEditor.getCursor(true),
to: htmlEditor.getCursor(false),
};
}
function autoFormatSelection() {
var range = getSelectedRange();
htmlEditor.autoFormatRange(range.from, range.to);
}
function commentSelection(isComment) {
var range = getSelectedRange(),
selStart = htmlEditor.getCursor("start");
htmlEditor.commentRange(isComment, range.from, range.to);
htmlEditor.setSelection(selStart, htmlEditor.getCursor("end"));
}
document.querySelector("#run-btn").addEventListener("click", function () {
let htmlCode = htmlEditor.getValue();
let previewWindow =
document.querySelector("#preview-window").contentWindow.document;
previewWindow.open();
previewWindow.write(htmlCode);
previewWindow.close();
});
</script>
</html>
如果实施得当,我们应该有以下结果。
结论
总之,我们学会了如何创建一个兼容HTML、CSS和JavaScript的编辑器。我们添加了一个HTML代码格式功能、自动完成功能、使用split.js的可调分屏。
我们将所有这些组件集合在一起,使用codemirror建立了一个响应式的代码编辑器。