前言:

首先,我这个文章不会写非常详细的代码,但是我会把我目前博客开发的富文本编辑遇到的问题罗列出来。然后一点点的说明如何解决。说实在目前遇到的问题,已经想让我放弃自己开发富文本了,真的是非诚勿扰。这个坑没那么简单。(捂脸哭)

开发环境:vueCli3.X

一、HTML5的富文本

contentEditable="true"

这个属性我不介绍了,不懂得自己百度

二、编写页面遇到的坑(点击事件失去焦点)

网上大多数富文本编辑器都是iframe,很多成熟的富文本编辑器也是用的iframe。我个人不知道好坏,所以我直接用的div。也许后期会遇到无法解决的坑再换吧。

我不知道是不是我不是用的iframe的问题,但是每当我需要操作文字加粗都失败,原因在于失去选区。

解决:a标签和img标签不会失去选区,改代码。

上个人代码:

<div class="dht-editor-operation">
      <template v-for="(item, index) in operationList">
        <a :key="index" @click="item.event" :title="item.title">
          <img :src="item.iconUrl" :style="item.backgroundImg" alt="" />
        </a>
      </template>
    </div>

三、我的文字不会加粗

我其实第一个写的功能是颜色选择器,没写很复杂就是用input的color属性

第二功能是文字加粗。但是不会加粗。最后检查得知是因为,我自己有一个全局存在的样式重置代码。我把b标签的默认样式去除了。

到这个时候我都还是用的富文本自己的操作函数

document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

文档地址:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand

这里开始就踩坑很严重了。因为样式重置,我考虑到如果别人用我的东西,那么也会这样,那就是说我得避免这个情况。所以我选择了另一条路,自己实现这些功能。当然不可能所有都自己实现,那就太累了,我也不是写产品,给自己用的。

解决方式

使用:window.getSelection()Range()

参考教程:https://www.jianshu.com/p/5997a90aab64

MDN文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Selection

MDN文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Range

这里文档得好好看看,不然我下面的代码你看不懂。

第一次解决方式

我用的代码是这样的(不要在意我这里是改颜色,原理懂了就行)

代码来自这篇博客:https://www.cnblogs.com/wyjs/articles/9733827.html

我个人一开始就是按这位的博客来写的,很详细

var selection = document.getSelection();
//取得选择的文本
var selectionText = selection.toString();
//取得代表选区的范围
var range = selection.getRangeAt(0);
//突出显示选择的文本
var span = document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);

这种方式用的是range.surroundContents,意思是将你选中的文档放在一个新的标签中。

但是问题很严重

缺点:

1、无限的加入标签中,会无限嵌套html元素(自己开发中看f12就懂了)

2、无法跨元素操作

比如这样的,这种选择是不能成功的,报错。因为他无法操作多个dom元素。

 

这时候已经巨坑了好吧。我原本以为就和别人说的一样,好简单。你要是不考虑那么多操作,不当初编辑器来操作确实简单啊。

第二种解决方式(目前我测试没什么问题)

原理在于先删后插,需要需要各位理解range选区(拖蓝部分的代码意思,仔细看文档咯)

这里还是会产生无限嵌套问题,我再找找方式,但是解决了跨元素选择问题

代码:

CursorAcquisition() {
      let selection = window.getSelection();
      let range = selection.getRangeAt(0);
      return {
        selection,
        range
      };
    },
//取得代表选区的范围
      let range = this.CursorAcquisition().range;
      //突出显示选择的文本
      //let rangeClone = range.cloneRange();
      //获得选中区域dom袁术
      let rangeText = range.extractContents();
      //创建新的dom并且结合
      let span = document.createElement("span");
      span.appendChild(rangeText);
      span.style.color = "red";
      //先移除选中节点
      range.deleteContents();
      //再插入节点
      range.insertNode(span);

这个代码就能实现上述所有产生的问题。至少我暂时这么认为,大神则请指出。

 

 

好了第一篇踩坑到此结束,各位请先品尝。后面我还会写下一篇。因为下一个坑我已经踩完了。心累。不写博客我都不知道哪里去发泄。网上的教程即好又缺斤少两,少关键啊。

最后附上,我的颜色选择器,不需要添加html元素。但是需要支持input color

//颜色选择器
    colorSelect() {
      let input = document.createElement("input");
      let that = this;
      input.type = "color";
      input.click();
      input.addEventListener("input", watchColorPicker, false);
      function watchColorPicker(event) {
        //console.log(event.target.value);
        let color = event.target.value;
        that.operationList[0].backgroundImg = {
          background: color
        };
        //移除监听
        input.removeEventListener("input", watchColorPicker, false);
        input = "";
      }
    }

个人项目代码都在git上面:

地址:https://github.com/ht-sauce/dream

本次富文本开发的路径截图,项目属于持续完善,所以代码比较乱。

项目富文本本地打开地址:http://localhost:8080/dht_blog/richTextEditor

 

项目的最后:

富文本肯定不是到这里就结束了,但是从目前自己代码的方式来写,不亚于放弃一切,然后构建一个新的文本编辑器。考虑代码重构,舍弃当前复杂的开发方式。从博文发出,到发现bug,再到重新百度富文本编辑器原理,经历了3个小时。实在没办法,真不是两三天能写完的。

下面我将开后端nodejs项目,研究koa框架和阿里的egg框架。计划开始搞自己的后端服务代码了。毕竟一个博客不能只是前端页面。但是,后端不会太深入,因为要有所侧重。因为都是nodejs,所以js代码方面不会荒废。

 

Logo

前往低代码交流专区

更多推荐