前言
写这篇文章的目的是为了记录自己第一次实现一个非常简易的富文本编辑器的过程,项目使用到了 Webpack 和 TypeScript。
项目介绍
项目目录文件
|-- 富文本编辑器,
|-- README.md,
|-- index.html,
|-- package-lock.json,
|-- package.json,
|-- tsconfig.json,
|-- webpack.build.config.js,
|-- webpack.config.js,
|-- dist,// 打包生成的文件
| |-- yangEditor.js,
|-- lib,
| |-- index.css,
| |-- index.js,
| |-- yangEditor.ts,
|-- src,
|-- index.js,
项目安装的依赖
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^5.2.0",
"html-webpack-plugin": "^5.3.1",
"style-loader": "^2.0.0",
"ts-loader": "^8.1.0",
"typescript": "^4.2.3",
"webpack": "^5.30.0",
"webpack-cli": "^4.6.0",
"webpack-dev-server": "^3.11.2"
webpack.config.js
开发环境的 Webpack
配置
const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
mode: "development",
entry: "./src/index.js",
devServer: {
port: 8089, // 设置端口号
},
module: {
rules: [
{
test: /\.ts$/,
use: "ts-loader",
exclude: /node_modules/
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./index.html"
})
]
}
webpack.build.config.js
生产环境的 Webpack
配置
const path = require("path")
module.exports = {
mode: "production",
entry: "./lib/index.js",
output: {
filename: "yangEditor.js",
path: path.resolve(__dirname, "./dist"),
libraryTarget: 'umd'
},
module: {
rules: [
{
test: /\.ts$/,
use: "ts-loader",
exclude: /node_modules/
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
}
}
项目运行命令
"scripts": {
"dev": "webpack serve --open Chrome.exe",
"build": "webpack --config webpack.build.config.js"
},
document.execCommand
当一个HTML文档切换到设计模式时,document
暴露 execCommand 方法,该方法允许运行命令来操纵可编辑内容区域的元素,本次项目实现富文本编辑器就是使用该它。
语法
bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)
,返回值是一个Boolean
,如果是false
则表示操作不被支持
或未被启用
。
参数
aCommandName
:一个 DOMString ,命令的名称。aShowDefaultUI
:是否展示用户界面,一般为 false。aValueArgument
:一些命令(例如insertImage)需要额外的参数(insertImage需要提供插入image的url),默认为null。
简易富文本具体实现
yangEditor.ts
首先我们创建一个类,传入一个DOM
节点字符串,获取DOM
节点。
export default class YangEditor {
constructor(dom: string) {
if (!dom) {
throw new Error('请传入DOM节点!!!');
}
let editWrapper: HTMLElement = document.getElementById(dom);
}
}
Command 指令
// 指令数组
const actions = [
{
command: 'formatblock',
values: [
{ text: '- 设置标题大小 -', value: 'selected' },
{ text: 'H1标题', value: 'h1' },
{ text: 'H2标题', value: 'h2' },
{ text: 'H3标题', value: 'h3' },
{ text: 'H4标题', value: 'h4' },
{ text: 'H5标题', value: 'h5' },
],
},
{
command: 'forecolor',
values: [
{ text: '- 设置字体颜色 -', value: 'selected' },
{ text: '红色', value: 'red' },
{ text: '蓝色', value: 'blue' },
{ text: '绿色', value: 'green' },
{ text: '黑色', value: 'black' },
],
},
{
command: 'bold',
values: [
{ text: '- 设置字体粗体 -', value: 'selected' },
{ text: '粗体', value: '' },
],
},
];
创建DOM
节点
// 创建DOM节点
private createDOM(type: string, className?: string): HTMLElement {
let dom = document.createElement(type);
dom.className = className || '';
return dom;
}
动态创建 select
标签
// 创建select节点
private createSelectDOM(commandItem: ActionsItem): HTMLSelectElement {
let select = document.createElement('select');
commandItem.values.forEach((item) => {
select.add(new Option(item.text, item.value));
select.id = `${commandItem.command}`;
});
select.onchange = () => {
// select标签onchange事件,调用execCommand方法
this.execCommand(commandItem.command, select.options[select.selectedIndex].value);
};
return select;
}
使用 document.execCommand
方法
private execCommand(cmd: string, value: string): void {
//execCommand bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)
// aCommandName 一个 DOMString ,命令的名称。
//aShowDefaultUI 一个 Boolean, 是否展示用户界面,一般为 false
//aValueArgument 一些命令(例如insertImage)需要额外的参数(insertImage需要提供插入image的url),默认为null。
document.execCommand(cmd, false, value);
}
使用方法
import { YangEditor } from "../lib/index"
new YangEditor("yangEdit")
实现效果
项目源码
编辑器源码地址
参考资料
MDN execCommand
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!