引言
在Web开发中,富文本编辑器是内容管理系统、博客平台和各种Web应用中不可或缺的组件。本文将详细介绍如何使用原生HTML、CSS和JavaScript创建一个自定义的富文本编辑器,包括基本的文本格式化功能、图片上传支持和字符计数等实用特性。
效果演示
技术选型
- HTML5:构建页面结构和基础功能
- CSS3:实现现代美观的界面样式
- 原生JavaScript:处理交互逻辑和核心功能
- ContentEditable API:实现富文本编辑核心功能
功能概览
- 文本格式化(加粗、斜体、下划线)
- 列表支持(有序列表、无序列表)
- 对齐方式(左对齐、居中对齐、右对齐)
- 链接插入
- 图片上传与预览
- 字符计数
- 键盘快捷键支持
- 按钮状态同步
页面结构
工具栏区域
富文本编辑器的工具栏(toolbar),包含以下功能按钮:加粗、斜体、下划线、无序列表、有序列表、左对齐、居中对齐、右对齐、插入链接、插入图片。
每个按钮都带有对应的SVG图标和提示文字,并为后续实现编辑器功能预留了命令标识(data-command属性)。
<div class="toolbar">
<div class="toolbar-group">
<button data-command="bold" title="加粗 (Ctrl+B)">
<svg>...</svg>
</button>
<button data-command="italic" title="斜体 (Ctrl+I)">
<svg>...</svg>
</button>
<button data-command="underline" title="下划线 (Ctrl+U)">
<svg>...</svg>
</button>
</div>
<div class="toolbar-group">
<button data-command="insertUnorderedList" title="无序列表">
<svg>...</svg>
</button>
<button data-command="insertOrderedList" title="有序列表">
<svg>...</svg>
</button>
</div>
<div class="toolbar-group">
<button data-command="justifyLeft" title="左对齐">
<svg>...</svg>
</button>
<button data-command="justifyCenter" title="居中对齐">
<svg>...</svg>
</button>
<button data-command="justifyRight" title="右对齐">
<svg>...</svg>
</button>
</div>
<div class="toolbar-group">
<button data-command="createLink" title="插入链接 (Ctrl+K)">
<svg>...</svg>
</button>
<button id="insertImage" title="插入图片">
<svg>...</svg>
</button>
<input type="file" id="imageUpload" accept="image/*">
</div>
</div>
编辑区域
富文本编辑器的主要编辑区域,contenteditable="true"
使该区域可编辑,用户可以直接在此输入和格式化文本。
<div id="editor" class="editor-content" contenteditable="true"></div>
状态栏区域
富文本编辑器的状态栏区域,实时显示用户输入的字符数量,监听上传进度的动态变化,增强交互体验。
<div class="status-bar">
<span id="charCount">0 字符</span>
<div class="upload-progress" id="uploadProgress">
<div class="upload-progress-bar" id="uploadProgressBar"></div>
</div>
</div>
核心功能实现
文本样式编辑
为工具栏中所有带有 data-command 属性的按钮添加了点击事件监听器,根据点击按钮的 data-command 值,调用 document.execCommand() 执行对应的编辑命令(如加粗、斜体、插入链接等)。
其中,对 createLink
命令单独处理,先检查是否有选中文本,再通过 prompt 获取链接地址,最后调用命令插入链接。对于 bold
、italic
和 underline
这些命令,根据当前文本格式状态,动态切换按钮的激活样式。
每次操作后重新将焦点放回编辑区域,确保用户可以继续输入或编辑。
document.querySelectorAll('.toolbar button[data-command]').forEach(button => {
button.addEventListener('click', function() {
const command = this.getAttribute('data-command');
// 处理特殊命令
if (command === 'createLink') {
const selection = window.getSelection();
if (selection.toString().length === 0) {
alert('请先选择要添加链接的文本');
return;
}
const url = prompt('输入链接地址:', 'https://');
if (url) {
document.execCommand(command, false, url);
}
} else {
document.execCommand(command, false, null);
// 切换按钮激活状态
if (['bold', 'italic', 'underline'].includes(command)) {
const isActive = document.queryCommandState(command);
this.classList.toggle('active', isActive);
}
}
editor.focus();
});
});
图片上传功能
点击【插入图片】按钮会触发隐藏的文件选择框弹出,选择图片文件后,进行格式和大小验证。
图片上传时,插入一个占位符显示“上传中”状态,显示上传进度条并模拟上传过程,使用 FileReader 将图片转换为 Data URL 模拟上传成功,成功后将占位符替换为真实图片,失败则移除占位符并提示错误。
insertImageBtn.addEventListener('click', function() {
imageUpload.click();
});
imageUpload.addEventListener('change', function(e