在Web开发中,富文本输入框结合实时预览的功能可以提升用户的编辑体验,让用户直观看到输入内容的最终呈现效果。结合Markdown轻量标记语言和JavaScript的原生能力,我们可以快速实现一个可定制化的富文本输入预览组件,不需要依赖第三方富文本库就能满足基础需求。

核心实现思路
整个组件主要由三个部分组成:Markdown输入框、实时预览区域、自定义配置模块。输入框负责接收用户的Markdown格式内容,JavaScript监听输入事件后,将内容解析为HTML,再渲染到预览区域,同时通过配置项可以调整解析规则、输入框样式等属性。
基础HTML结构搭建
首先我们需要搭建组件的基础结构,包含输入框和预览区域两个核心容器,同时预留配置参数的挂载点:
<div class="markdown-editor-container">
<div class="editor-config">
<label>是否开启标题解析:<input type="checkbox" id="parseHeading" checked></label>
<label>是否开启链接解析:<input type="checkbox" id="parseLink" checked></label>
</div>
<div class="editor-body">
<textarea id="markdownInput" placeholder="请输入Markdown内容..."></textarea>
<div id="previewArea" class="preview-area"></div>
</div>
</div>
样式定义
给组件添加基础样式,让输入框和预览区域并排显示,提升使用体验:
.markdown-editor-container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.editor-config {
margin-bottom: 16px;
padding: 12px;
background: #f5f5f5;
border-radius: 4px;
}
.editor-config label {
margin-right: 20px;
cursor: pointer;
}
.editor-body {
display: flex;
gap: 20px;
height: 500px;
}
#markdownInput {
flex: 1;
padding: 16px;
border: 1px solid #ddd;
border-radius: 4px;
resize: none;
font-size: 14px;
line-height: 1.6;
}
.preview-area {
flex: 1;
padding: 16px;
border: 1px solid #ddd;
border-radius: 4px;
overflow-y: auto;
background: #fff;
line-height: 1.6;
}
.preview-area h1, .preview-area h2, .preview-area h3 {
margin-top: 0;
}
.preview-area a {
color: #1890ff;
text-decoration: none;
}
.preview-area a:hover {
text-decoration: underline;
}
Markdown解析逻辑实现
接下来实现核心的Markdown解析函数,这里我们先处理基础的语法,包括标题、加粗、链接,同时支持根据配置项开关对应解析规则:
/**
* 解析Markdown内容为HTML
* @param {string} markdownText - 输入的Markdown文本
* @param {Object} config - 解析配置项
* @returns {string} 解析后的HTML字符串
*/
function parseMarkdown(markdownText, config) {
let html = markdownText;
// 解析标题,支持h1到h3,根据配置开关决定是否解析
if (config.parseHeading) {
html = html.replace(/^### (.*$)/gim, '<h3>$1</h3>');
html = html.replace(/^## (.*$)/gim, '<h2>$1</h2>');
html = html.replace(/^# (.*$)/gim, '<h1>$1</h1>');
}
// 解析加粗语法 **文本**
html = html.replace(/**(.*?)**/gim, '<strong>$1</strong>');
// 解析链接语法 [文本](url),根据配置开关决定是否解析
if (config.parseLink) {
html = html.replace(/[([^[]+)](([^)]+))/gim, '<a href="$2">$1</a>');
}
// 处理换行符,转换为br标签
html = html.replace(/n/g, '<br>');
return html;
}
实时预览功能绑定
我们需要监听输入框的输入事件,每次内容变化时重新解析并渲染预览区域,同时读取配置项的当前状态:
// 获取DOM元素
const markdownInput = document.getElementById('markdownInput');
const previewArea = document.getElementById('previewArea');
const parseHeadingCheckbox = document.getElementById('parseHeading');
const parseLinkCheckbox = document.getElementById('parseLink');
/**
* 更新预览区域内容
*/
function updatePreview() {
// 获取当前配置状态
const config = {
parseHeading: parseHeadingCheckbox.checked,
parseLink: parseLinkCheckbox.checked
};
// 获取输入框内容并解析
const markdownText = markdownInput.value;
const htmlContent = parseMarkdown(markdownText, config);
// 渲染到预览区域
previewArea.innerHTML = htmlContent;
}
// 监听输入框输入事件
markdownInput.addEventListener('input', updatePreview);
// 监听配置项变化事件
parseHeadingCheckbox.addEventListener('change', updatePreview);
parseLinkCheckbox.addEventListener('change', updatePreview);
// 初始化时触发一次预览更新,显示默认内容
markdownInput.value = '# 欢迎使用Markdown编辑器n这是一段**加粗文本**,[点击访问ipipp.com](https://ipipp.com)';
updatePreview();
组件定制化扩展
如果需要进一步扩展组件能力,可以基于现有逻辑做调整:
- 增加更多Markdown语法解析,比如列表、代码块、引用等,只需要在
parseMarkdown函数中添加对应的正则替换规则即可 - 支持自定义输入框和预览区域的样式,通过给容器添加自定义class,在CSS中覆盖默认样式
- 增加内容保存功能,监听输入框失焦事件,将当前Markdown内容存储到本地或者发送到后端接口
- 添加语法高亮功能,引入highlight.js等库,对解析后的代码块内容做高亮处理
注意事项
在实际使用中需要注意几个问题:
如果用户输入的内容包含恶意HTML标签,直接渲染innerHTML可能存在XSS风险,生产环境需要添加内容过滤逻辑,对输入内容做安全校验,避免执行恶意脚本。另外正则解析Markdown的方式只适合处理简单语法,复杂的Markdown嵌套场景可能会出现解析错误,如果需要支持完整的Markdown语法,可以替换为专业的Markdown解析库,比如marked.js,只需要调整parseMarkdown函数的实现即可,整体组件结构不需要大改。
MarkdownJavaScript富文本输入框实时预览修改时间:2026-06-18 10:21:43