Angular实现textarea中JSON实时语法高亮需求及问题
Angular JSON输入实时语法高亮实现方案
核心问题分析
你当前代码的关键问题是:textarea不支持渲染HTML内容,设置innerHTML的操作完全无效,因为textarea仅能处理纯文本。此外你的colorizeJSON函数还存在两个缺陷:
- 未处理JSON数组的情况
- 输出的JSON键没有添加双引号,不符合标准JSON格式
方案一:用contenteditable div替代textarea(推荐)
这种方式可以直接渲染HTML高亮内容,同时兼容Angular表单控件:
HTML代码
<div class="json-editor" contenteditable="true" placeholder="required name and schemaJson object" [formControl]="schemaControl" (input)="updateHighlight()"> </div>
TypeScript代码
import { Component, OnInit } from '@angular/core'; import { FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-json-editor', templateUrl: './json-editor.component.html', styleUrls: ['./json-editor.component.css'] }) export class JsonEditorComponent implements OnInit { schemaControl = new FormControl('', Validators.required); originalText = ''; ngOnInit(): void { this.schemaControl.valueChanges.subscribe(value => { this.originalText = value || ''; }); } updateHighlight(): void { const editor = document.querySelector('.json-editor') as HTMLElement; try { const parsed = JSON.parse(this.originalText.trim()); editor.innerHTML = this.colorizeJSON(parsed); } catch (e) { editor.innerText = this.originalText; } } colorizeJSON(obj: any): string { if (Array.isArray(obj)) { let arrayStr = '['; obj.forEach((item, index) => { arrayStr += this.colorizeJSON(item); if (index !== obj.length - 1) arrayStr += ', '; }); return arrayStr + ']'; } if (typeof obj === 'object' && obj !== null) { let objStr = '{'; const keys = Object.keys(obj); keys.forEach((key, index) => { objStr += `<span class="json-key">"${key}"</span>: `; objStr += this.colorizeJSON(obj[key]); if (index !== keys.length - 1) objStr += ', '; }); return objStr + '}'; } let valueStr = String(obj); if (typeof obj === 'string') { valueStr = `"${valueStr}"`; } return `<span class="json-value">${valueStr}</span>`; } }
CSS代码
.json-editor { width: 100%; min-height: 200px; padding: 10px; border: 1px solid #ced4da; border-radius: 4px; font-family: monospace; white-space: pre-wrap; word-wrap: break-word; } .json-editor[contenteditable]:empty::before { content: attr(placeholder); color: #999; } .json-key { color: #268bd2; font-weight: bold; } .json-value { color: #2aa198; }
方案二:坚持使用textarea(复杂版)
如果必须保留textarea,需要通过隐藏的辅助div计算高亮位置,再通过selectionStart/selectionEnd和动态样式实现,但这种方式需要处理光标位置同步、滚动同步等问题,代码复杂度高,不推荐。
关于Ngx-monaco的补充
如果后续想重新尝试Ngx-monaco,核心注意点:
- 确保正确安装依赖:
npm install monaco-editor ngx-monaco-editor - 在
angular.json中配置monaco的assets路径 - 组件中正确初始化编辑器并设置语言为
json
内容的提问来源于stack exchange,提问作者Jihed Ben Zarb
相关产品推荐
相关产品推荐

