AVUE 富文本编辑器 avue-plugin-ueditor 格式刷功能 ver.0.2.7
avue 在线编辑器 avue-plugin-ueditor增加格式刷功能
·
avue-plugin-ueditor 版本:0.2.7
背景:
依据操作人员需求,认为目前在线编辑器没有ckeditor好用,也没有格式化的功能,目前项目是基于avue框架开发,使用了avue-plugin-ueditor插件,它整合了wangEditor4版本,wangEditor作者明确不在4版本增加格式刷功能。
查找多方资料,经过调试修改已实现格式化功能。废话不多说,直接上代码。
样例:
依据wangEditor官网v4版本自定菜单说明,见快速扩展一个菜单 · wangEditor 用户文档。
因此在vue项目中新建formatterPainter.js(格式化继承BtnMenu)。
import E from "wangeditor";
const { BtnMenu } = E;
// 第一,菜单 class ,Button 菜单继承 BtnMenu class
class FormatterPainterBtn extends BtnMenu {
constructor(editor) {
// data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
// 图表直接用的element-ui的图标,请自行调整
const $elem = E.$(
//使用下面写法调用active()、unActive()方法自动修改css样式
'<div class="w-e-menu" data-title="格式刷"><i class="w-e-menu el-icon-s-open"></div>');
super($elem, editor);
const me = this;
me.editor = editor;
// 监听编辑器鼠标释放事件
editor.$textElem.on("mouseup", () => {
// 如果格式刷功能出于激活状态
if (me._active) {
// 延迟执行,避免获取不到正确的元素
setTimeout(() => {
// 复制格式刷样式
pasteStyle(editor);
// 取消格式刷激活样式
me.unActive();
}, 100);
}
});
}
// 菜单点击事件
clickHandler() {
const me = this;
const editor = me.editor;
// debugger
if (me._active) {
// 已经在激活状态时取消激活
me.unActive();
// 清空格式刷样式数据
editor.copyStyleList = []
} else {
// 没有选中则中断
if (editor.selection.isSelectionEmpty())
return;
// 激活按钮
me.active();
// 获取格式刷样式
const domToParse =
editor.selection.getSelectionContainerElem().elems[0];
const copyStyleList = parseDom(domToParse);
// 保存格式刷样式
editor.copyStyleList = copyStyleList;
}
}
// 菜单是否被激活(如果不需要,这个函数可以空着)
// 1. 激活是什么?光标放在一段加粗、下划线的文本时,菜单栏里的 B 和 U 被激活,如下图
// 2. 什么时候执行这个函数?每次编辑器区域的选区变化(如鼠标操作、键盘操作等),都会触发各个菜单的 tryChangeActive 函数,重新计算菜单的激活状态
tryChangeActive() {}
}
// 菜单 key ,各个菜单不能重复
const menuKey = "foramtterPainter";
// 注册菜单
E.registerMenu(menuKey, FormatterPainterBtn);
// 复制选中dom的样式
function parseDom(dom) {
let targetDom = null;
const nodeArray = [];
getTargetDom(dom);
getAllStyle(targetDom);
function getTargetDom(dom) {
for (const i of dom.childNodes) {
if (i.nodeType === 3 && i.nodeValue && i.nodeValue.trim() !== "") {
targetDom = dom;
return;
}
}
getTargetDom(dom.children[0]);
}
function getAllStyle(dom) {
if (!dom)
return;
const tagName = dom.tagName.toLowerCase();
if (tagName === "p") {
nodeArray.push({
tagName: "span",
attributes: Array.from(dom.attributes).map((i) => {
return {
name: i.name,
value: i.value
};
})
});
return;
} else {
nodeArray.push({
tagName: tagName,
attributes: Array.from(dom.attributes).map((i) => {
return {
name: i.name,
value: i.value
};
})
});
getAllStyle(dom.parentNode);
}
}
return nodeArray;
}
function addStyle(text, nodeArray) {
let currentNode = null;
nodeArray.forEach((ele, index) => {
const node = document.createElement(ele.tagName);
for (const attr of ele.attributes) {
node.setAttribute(attr.name, attr.value);
}
if (index === 0) {
node.innerText = text;
currentNode = node;
} else {
node.appendChild(currentNode);
currentNode = node;
}
});
return currentNode;
}
// 粘贴
function pasteStyle(editor) {
// 获取格式刷保存的样式
const copyStyleList = editor.copyStyleList;
// 有样式说明格式刷被激活
if (copyStyleList) {
// 获取当前选中内容
// 如果没选中也会执行,再次使用需要重新激活格式刷功能
const text = editor.selection.getSelectionText();
const targetDom = addStyle(text, copyStyleList);
editor.cmd.do("insertHTML", targetDom.outerHTML);
// 清空格式刷样式
editor.copyStyleList = null;
}
}
上述js文件使用了全局注册的方式,因此在main.js中引入该扩展按钮文件。
// main.js
import formatterPainter from "./components/editor/formatterPainter"
然后就OK了。给出一个例子:
{
"type": "ueditor",
// 指定插件类型为在线编辑器
"component": 'avueUeditor',
"label": "新闻内容",
"prop": "contentCn",
"span": 24,
// 上传路径
"action": "/portal/common/local/attach/upload",
"data": {
// 额外参数
"folder": "news",
},
"propsHttp": {
// 上传完成返回的json的root
"res": "data",
// 上传完成返回的图片路径
"url": "fileUrl",
// 上传文件名,默认file
"fileName": "attach",
},
"customConfig": {
// 写wangEditor.config中的配置项,例如下面所示excludeMenus、menus官网建议只写其中一个
// showMenuTooltips: false
// "excludeMenus": ['video']
// menus: [
// 'bold',
// 'head',
// 'link',
// 'italic',
// 'underline'
// ]
},
"overHidden": true
}
至此大功告成!
效果图:
注意点:
1、如果有关按钮不生效,可以尝试修改chrome浏览器,显示不安全的内容。
2、格式刷在刷新格式的时候需要注意不要移动到编辑器外面去了。
更多推荐
已为社区贡献4条内容
所有评论(0)