AVUE 富文本编辑器 avue-plugin-ueditor 格式刷功能 ver.0.2.7

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、格式刷在刷新格式的时候需要注意不要移动到编辑器外面去了。

文章主要参考:vue 中 wangeditor 格式刷功能 - 魔狼再世 - 博客园

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sword_happy

您的鼓励亦是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值