能够实时进行语法高亮的文本框?

245

为了更容易的维护,我将许多HTML块存储在CMS中。它们由<textarea>表示。

有没有人知道某种JavaScript小部件能够在<textarea>或类似元素中对HTML进行语法高亮,同时仍然保持纯文本编辑器(无所见即所得或高级功能)?


1
W3C是否有可能在未来版本的(X)HTML规范和相关标准中使textarea更加多才多艺和可扩展? - James Haigh
3
@FabienMénager,你的重复链接已被删除。 - Patrick Roberts
5
这会有所帮助 http://codepen.io/kazzkiq/pen/xGXaKR/ - Shan Eapen Koshy
11个回答

260

3
实际上,Bespin使用常规的文本区域回退功能来支持屏幕阅读器(以便残障人士也能轻松使用它)。 - Eli Grey
4
CodeMirror 看起来正是我需要的。只要它像文本区一样运作,我就不介意它不是文本区。 - Pekka
1
谢谢你的回答。在阅读了你的回复后,我发现了这个项目,它让我大开眼界! :) https://github.com/securingsincity/react-ace - currenthandle
使用普通文本区域进行语法高亮是完全可能的,这实际上就是所有那些所谓的运行程序的基础。通常人们会使用JS来创建文本区域,而不是仅仅使用HTML。因此,这个回答并不正确,这个问题通常是由高级程序员制作的。 - RagDev

32

这是我对类似问题所做出的回答(链接1),使用在线代码编辑器(链接2),发布在程序员(链接3)上:

首先,您可以参考这篇文章:
维基百科 ― 基于JavaScript的源代码编辑器比较

此外,以下是一些看起来符合您需求的工具:

  • EditArea文件编辑器演示 是一个Yii扩展 ― (Apache软件许可证,BSD,LGPL

    这是EditArea,一个用于源代码的免费JavaScript编辑器。它允许编写格式良好的源代码,具有行号、制表符支持、搜索和替换(使用正则表达式)以及实时语法高亮显示(可自定义)。

  • CodePressJoomla! CodePress插件演示 ― (LGPL) ― 它在Chrome中不起作用,而且看起来开发已经停止了。

    CodePress是一款基于Web的源代码编辑器,具有JavaScript编写的语法高亮显示功能,可以在文本在浏览器中输入时进行实时着色。

  • CodeMirror众多演示之一 ― (MIT-style许可证+可选商业支持

    CodeMirror是一个JavaScript库,可用于为类似代码的内容(计算机程序、HTML标记等)创建相对愉悦的编辑器界面。如果已为您正在编辑的语言编写了模式,代码将被着色,并且编辑器将可选择地帮助您缩进。

  • Ace Ajax.org Cloud9 Editor演示 ― (Mozilla三重许可证(MPL/GPL/LGPL)

    Ace是一个独立的JavaScript代码编辑器。我们的目标是创建一个与现有本机编辑器(如TextMate、Vim或Eclipse)匹配并扩展其功能、易用性和性能的基于Web的代码编辑器。它可以轻松地嵌入任何Web页面和JavaScript应用程序中。Ace是Cloud9 IDE的主要编辑器,并且是Mozilla Skywriter(Bespin)项目的继承者。


2
哦,这真是令人沮丧...有100个项目都应该能做到这一点,但绝对没有一个可以正常工作。 - RobinJ
Ace编辑器的许可证已更改为BSD https://github.com/ajaxorg/ace/blob/master/LICENSE - S.Krishna

19

13

11
我建议使用EditArea来实现对语法高亮文本区域的实时编辑。

8

在文本域内实际上无法呈现标记语言。

但是,您可以通过仔细地将一个 div 定位在文本域后面并在其中添加高亮的标记语言来模拟它。

JavaScript 负责同步内容和滚动位置。

var $container = $('.container');
var $backdrop = $('.backdrop');
var $highlights = $('.highlights');
var $textarea = $('textarea');
var $toggle = $('button');


var ua = window.navigator.userAgent.toLowerCase();
var isIE = !!ua.match(/msie|trident\/7|edge/);
var isWinPhone = ua.indexOf('windows phone') !== -1;
var isIOS = !isWinPhone && !!ua.match(/ipad|iphone|ipod/);

function applyHighlights(text) {
  text = text
    .replace(/\n$/g, '\n\n')
    .replace(/[A-Z].*?\b/g, '<mark>$&</mark>');

  if (isIE) {
    // IE wraps whitespace differently in a div vs textarea, this fixes it
    text = text.replace(/ /g, ' <wbr>');
  }

  return text;
}

function handleInput() {
  var text = $textarea.val();
  var highlightedText = applyHighlights(text);
  $highlights.html(highlightedText);
}

function handleScroll() {
  var scrollTop = $textarea.scrollTop();
  $backdrop.scrollTop(scrollTop);

  var scrollLeft = $textarea.scrollLeft();
  $backdrop.scrollLeft(scrollLeft);
}

function fixIOS() {
  $highlights.css({
    'padding-left': '+=3px',
    'padding-right': '+=3px'
  });
}

function bindEvents() {
  $textarea.on({
    'input': handleInput,
    'scroll': handleScroll
  });
}

if (isIOS) {
  fixIOS();
}

bindEvents();
handleInput();
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 30px;
  background-color: #fff;
  caret-color: #000;
}

.container,
.backdrop,
textarea {
  width: 460px;
  height: 180px;
}

.highlights,
textarea {
  padding: 10px;
  font: 20px/28px 'Open Sans', sans-serif;
  letter-spacing: 1px;
}

.container {
  display: block;
  margin: 0 auto;
  transform: translateZ(0);
  -webkit-text-size-adjust: none;
}

.backdrop {
  position: absolute;
  z-index: 1;
  border: 2px solid #685972;
  background-color: #fff;
  overflow: auto;
  pointer-events: none;
  transition: transform 1s;
}

.highlights {
  white-space: pre-wrap;
  word-wrap: break-word;
  color: #000;
}

textarea {
  display: block;
  position: absolute;
  z-index: 2;
  margin: 0;
  border: 2px solid #74637f;
  border-radius: 0;
  color: transparent;
  background-color: transparent;
  overflow: auto;
  resize: none;
  transition: transform 1s;
}

mark {
  border-radius: 3px;
  color: red;
  background-color: transparent;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div class="backdrop">
    <div class="highlights"></div>
  </div>
  <textarea>All capitalized Words will be highlighted. Try Typing to see how it Works</textarea>
</div>

原始文档:https://codepen.io/lonekorean/pen/gaLEMR


至少在应该给予 skid 信用时,我已经在网站的其他地方看到了这段完全相同的代码。 - Crimin4L
这是 CodePen 中一个稍微修改过的笔的版本。 - A5H1Q
原来的突出背景,而这个突出文本。 - A5H1Q

7

更新:现在Bespin已经更名为ACE,这也是本文中最高评分答案提到的。请使用ACE。

我选择Mozilla的Bespin。它使用HTML5特性构建(因此速度快,但不支持旧版浏览器),但绝对好用,击败了我所遇到的所有工具 - 可能是因为Mozilla支持它,并且他们开发Firefox,所以...还有一个jQuery插件包含它的扩展功能,使其与jQuery一起使用更加容易。


5

1

1
Ace是Mozilla Bespin项目的继任者。 - hbd

0

16
这些插件不允许像文本区域一样实时进行语法高亮。 - Fabien Ménager
1
链接已损坏。 - mimic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接