首先,我这个文章不会写非常详细的代码,但是我会把我目前博客开发的富文本编辑遇到的问题罗列出来。然后一点点的说明如何解决。说实在目前遇到的问题,已经想让我放弃自己开发富文本了,真的是非诚勿扰。这个坑没那么简单。(捂脸哭)
开发环境:vueCli3.X
contentEditable="true"
这个属性我不介绍了,不懂得自己百度
网上大多数富文本编辑器都是iframe,很多成熟的富文本编辑器也是用的iframe。我个人不知道好坏,所以我直接用的div。也许后期会遇到无法解决的坑再换吧。
我不知道是不是我不是用的iframe的问题,但是每当我需要操作文字加粗都失败,原因在于失去选区。
解决:a标签和img标签不会失去选区,改代码。
上个人代码:
我其实第一个写的功能是颜色选择器,没写很复杂就是用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代码方面不会荒废。