使用Ts从零实现以一个简易编辑器

Jere

小目标

  1. 使用ts从零实现一个简单的富文本编辑器
  2. 初步实现“设置标题”,“加粗”,“设置颜色”这几个基本功能

知识准备

  1. contenteditable属性

    给任何一个元素加上contenteditable="true" 便可使其可编辑,由此为基础便可实现一个简单的富文本编辑器了。

    <div contenteditable="true"></div>
  2. Document.execCommand()

    当HTML文档切换到designMode时,它的文档对象将公开一个execCommand方法来运行操作当前可编辑区域的命令,如表单输入或可满足元素。

    document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

实现过程

  1. 初始化项目
    "lint": "eslint . --ext .js,.ts",
    "build": "webpack --env production",
    "start": "webpack-cli serve"

    基于webpack搭建一个基础项目,yarn start 用于本地开发。yarn build 用于构建生产文件。

  2. 确定简易富文本编辑器的调用方式
    import Editor from '../src/editor';
    
    new Editor('#editor_root', {
      style: {
        height: '300px',
      },
    });
  3. 初始化编辑器结构

    image-20201110140645515

  4. 实现编辑器菜单

    image-20201110140958264

  5. 解决range丢失的问题

    当编辑器失去焦点的时候,会导致当前选中的文本丢失。所以在编辑器失去焦点的事件触发时保存当前range

    backupRange(): void {
        const selection = window.getSelection();
        const range = selection.getRangeAt(0);
        this.currentSelection = {
          startContainer: range.startContainer,
          startOffset: range.startOffset,
          endContainer: range.endContainer,
          endOffset: range.endOffset,
        };
    }

    在执行操作之前,恢复之前的rangee

      restoreRange(): void {
        if (this.currentSelection) {
          const selection = window.getSelection();
          selection.removeAllRanges();
          const range = document.createRange();
          range.setStart(
            this.currentSelection.startContainer,
            this.currentSelection.startOffset,
          );
          range.setEnd(
            this.currentSelection.endContainer,
            this.currentSelection.endOffset,
          );
          // 向选区中添加一个区域
          selection.addRange(range);
        }
      }

总结

  1. 简易富文本编辑器的基本功能已实现
  2. webpack目前尚不支持export library 为es6 module
  3. 尚未添加单元测试
  4. document.execCommand已被标记为Obsolete

源码地址

阅读 403

前端拾遗
分享是最好的学习,

不忘初心,砥砺前行。

93 声望
4 粉丝
0 条评论
你知道吗?

不忘初心,砥砺前行。

93 声望
4 粉丝
宣传栏