从零开始撸富文本编辑器

1,877 阅读3分钟

前言

  本篇主要记录实现一个简单的富文本编辑器的主要实现思路和开发过程

功能描述

  1. 按功能区域来看,富文本编辑器一般主要包括两个部分 菜单栏文本编辑区域。菜单栏用于设置输入框的文本格式,如字体大小、字体颜色、字号、标题、背景、行高、缩减等等。文本编辑区域用于输入富文本内容。

  2. 因为是目标是为了实现一个尽量简单的但是包含富文本主体功能的富文本编辑器,这里只选择标题、加粗、字体颜色三个菜单功能实现。

实现原理& 思路

  • 核心原理是基于html5的contenteditable属性,将元素调整成可编辑状态。然后再点击菜单时调用 document.execCommand方法操纵可编辑内容区域的元素调整编辑的状态格式。
  • 开发思路主要参考目前国内主流的开源wangEditor, 包括项目框架、模块划分、实现原理均保持一致。也可以理解为在学习wangEditor源码的过程中,抽离出的一个精简版的miniEditor
  • 效果图 image.png

开发过程

  1. 第一步搭建框架 项目框架部分在参考wangEditor的基础上删除了用不到的内容,比如server部分只用到了静态服务,examples只配置了一个index.html用于开发调试,主要包括如下内容。
  • build 构建脚本
  • server(基于kosa的静态服务,本地开发调试使用)
  • examples 示例文件(也是调试文件)
  • package.json构建脚本配置。
  1. src 代码模块划分 代码src部分主要由如下几部分构成
  • assets 字体图标和less静态文件
  • editor 编辑器主类
  • menus 菜单相关类

image.png

  1. 核心代码说明
  • 编辑器主要由Editor类实现 实现如下,主要包括动态创建富文本各区域,和初始化如菜单文本区等内容。
class Editor {
    public editorSelector: HTMLElement 

    public toolbarElem : HTMLElement
    public textContainerElem : HTMLElement
    public textElem : HTMLElement

    public menus : Menu[]

    public selectionApi : SelectionApi
    constructor(textSelector: HTMLElement){
        this.editorSelector = textSelector;
        this.toolbarElem =  document.createElement('div');
        this.textContainerElem = document.createElement('div');
        this.textElem = document.createElement('div');

        this.menus = [];
        this.selectionApi = new SelectionApi(this);

        this.initFramework();

        this.initMenu();

        this.initText();
    }
  • 菜单类以比如粗体做说明,主要步骤是给菜单初始化dom结构,然后绑定点击事件,再点击时,回复选区然后执行 document.execCommand。字体、颜色菜单实现方式类似,主要区别是多一个下拉菜单,execCommand在下拉菜单子项执行,且会多一个参数
class Bold extends Menu implements MenuActive {
    constructor(editor: Editor){
        const elem = createElemByHtml(`
        <div class="mini-menu-item" data-title="加粗">
            <i class="mini-e-icon-bold"></i>
        </div>
        `);
        super(elem[0], editor)
    }
    public clickHandler(): void {
        this.editorInstance.selectionApi.restoreSelection();
        document.execCommand('bold', false);
    }
    public changeActive(): void {
        const editor = this.editorInstance
    }
}

总结&收获

  • 该富文本编辑器的代码主要学习自wangEditor。为了尽量简单实现功能的文件尽量少一点,对其中的一些功能做了删减。比如没有使用自带的类似jquery的dom类,直接用原生的方法操作dom。删减下拉菜单的继承类;删减了server中其他非静态服务的功能;删减了配置项和插件扩展等。主要的代码class只有5个。
  • 通过对wangEditor的源码学习,大致了解了一个轻量级的富文本编辑器的实现方式,加深了ts和webpack的了解。

有想要了解代码的小伙伴可以在这里查看 github仓库