最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 通过Webpack+TS实现一个简易的富文本编辑器

    正文概述 掘金(可小乐)   2021-02-21   855

    概述

    这篇文章主要是来记录一下通过Webpack+TS实现的一个富文本编辑器。

    主要功能如下:

    1. 实现一个编辑区域
    2. 实现"加粗", "设置标题", "设置颜色"三个简易功能

    Webpack配置

    既然决定要使用TS,那么就可以通过webpack搭配ts-loader或者awesome-typescript-loader来对ts语言进行编译。相应的webpack配置文件也非常好写,这里就简单贴张截图。

    通过Webpack+TS实现一个简易的富文本编辑器

    开发流程

    接下来,我将自上而下来描述我是如何将这个富文本编辑器实现出来的。

    设计思路

    我认为首先应该从使用的角度入手,也就是说假设所有的功能都以及实现好了,通过这种假象的方式来决定我们的整个项目结构。 我这里的话是参考了wangeditor的使用方式:

    const Editor = window.Editor;
    const editor = new E('#container');
    editor.create()
    

    于是呢,我便依样画葫芦,我的简易编辑器使用方式如下:

    const editorDom = document.getElementById("root");
    const editor = new EasyEditor(editorDom);
    editor.create();
    window.editor = editor;
    

    与wangeditor不同点就在于传入构造函数的参数不同,我要求传入的是一个dom节点,而wangeditor要求传入的是一个类似于jquery获取元素的参数值。

    实现富文本编辑器关键问题

    1. 实现一个编辑区域

    这个非常简单,只要留意过H5新Api的小伙伴应该都会注意到contenteditable属性. 只要将该属性设置为true。那么该DOM元素的区域就是一个可编辑区域。

    1. 实现"加粗", "设置标题", "设置颜色"三个简易功能

    可以说,这三个功能其实都是对某部分字体加上样式,通过一番资料查阅,我发现浏览器提供给我们一个api: document.execCommand, 该api允许我们运行命令来操纵可编辑内容区域的元素。

    下面做一个小演示:

    首先我们在编辑区域选中一段字体: 通过Webpack+TS实现一个简易的富文本编辑器

    然后我们在控制台执行document.execCommand("bold", false, null), 将选中部分字体加粗

    通过Webpack+TS实现一个简易的富文本编辑器

    函数执行返回true, 即浏览器支持该操作; 若返回false, 那就是不支持该操作。

    除了加粗外,还有其它很多命令,如设置font-size,设置color等。在MDN上都有说明。

    至此,我们逐个击破了两大主要问题,接下来就是通过代码来进行实现啦。

    代码实现

    虽然功能简单, 但代码还是不少的, 因此下面只贴出重要的代码。

    初始化菜单栏以及编辑区

    菜单项栏是通过一个menuItems数组来动态渲染的,可以由用户提供,若用户没有提供,则使用系统自带的。

    [
            {
                text: "H",
                children: [
                    { text: '一级标题', command: 'fontSize-6' },
                    { text: '二级标题', command: 'fontSize-5' },
                    { text: '三级标题', command: 'fontSize-4' },
                    { text: '四级标题', command: 'fontSize-3' },
                    { text: '五级标题', command: 'fontSize-2' },
                    { text: '六级标题', command: 'fontSize-1' }
                ]
            },
            {
                text: "B",
                command: "bold"
            },
            {
                text: "C",
                children: [
                    {text: "red", command: "foreColor-red"},
                    {text: "blue", command: "foreColor-blue"},
                    {text: "green", command: "foreColor-green"},
                ]
            }
    ]
    

    文本编辑区中,默认换行使用的是div,参照wangeditor的,使用document.execCommand("defaultParagraphSeparator", false, "p")可以将默认换行标签改成p标签

    在渲染菜单项的时候,是允许有二级菜单的。同时,command会通过setAttribute绑定到生成的dom上。以便后续对编辑区域进行操作。

    最后还有一个问题,那就是当选中了编辑区中部分内容后,点击菜单栏按钮会失去选中部分。这样document.execCommand就失效了。

    我的解决办法是: 每次鼠标抬起时都将当前选中的部分缓存起来,以便后续虽然失去选中部分,但仍然可以找回选中部分。经过一番资料查阅,我找到了window.getSelection这个函数可以返回用户选择文本的一些信息,以下是MDN官方文档提供的示例:

    function foo() {
        let selection = window.getSelection();
        let cacheRange = selObj.getRangeAt(0);
        // 其他代码
    }
    

    拿到cacheRange那这就好办了,这要把它存起来,等到点击菜单栏的时候,再把它放回selection中,然后使用document.execCommand执行命令即可。

    function initEvent(dom: HTMLElement,editor: EasyEditor) {
    	// 绑定鼠标抬起缓存range事件
        dom.addEventListener("mouseup", function(e) {
            editor.cacheRange = window.getSelection().getRangeAt(0);
        })
    }
    
    // 通过事件委托, 把每个菜单项的点击事件委托到菜单上
    menuDom.addEventListener('click', function(e) {
        const targetDom = e.target as HTMLElement;
        const command = targetDom.getAttribute('command');
        if(!command) return ;
        if(editor.cacheRange) {
            const selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(editor.cacheRange);
            handleCommand(command); // 解析并执行绑定在dom上的命令
        }
    })
    

    效果截图

    通过Webpack+TS实现一个简易的富文本编辑器

    总结

    整个实现的过程为两天,有一天半的时间花在了调研查资料,工程规划上。写代码时间占比还是比较少的。

    从0到1实现了一个富文本编辑器,可以说是很少有这种经历,以往都是在算法上掰扯,精心实现某一个模块,对写工程的经验比较少,还是得多多练习。


    起源地下载网 » 通过Webpack+TS实现一个简易的富文本编辑器

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元