tinymce实现富文本设置高亮 高亮回显;应用场景如:数字教材高亮 数字教材标注 数字教材评论 数字教材纠错 等功能

阅读本文前提: 需要已引入tinymce

高亮流程

  1. 编辑器配置
  2. 预览高亮

编辑过程中插入自定义属性

编辑时为元素插入 特定的属性(本文案例使用:data-id=自定义ID) 用于判断选区;

因插入过程需要考虑 手动插入 、复制插入 此处单独拿出一篇文章查阅 点击查看

添加高亮

—— 获取目前选区的节点数据

查看如何获取目前选区的节点数据

将选区数据设置为高亮

注意点!!!!!

如果元素为readonly模式(预览模式)下,在设置高亮之前需要先将模式设置为编辑模式,selectAndHighlightText会返回一个Promise 在设定结束后再恢复readonly

/**
 * 解析实现高亮
 * @param { String } id 当前的tinymce ID
 * @param { handleHeight 的 returns } start 第一步获取到的 目前选区的节点数据
 * @param { handleHeight 的 returns } end  第一步获取到的 目前选区的节点数据
 * @param { String } color 标注的背景颜色
*/
export const selectAndHighlightText = (hid,id,startConfig,endConfig,color) => {
    return new Promise((resolve,reject)=>{ 
        let editor = window.tinymce.get(id)
        var range = tinymce.activeEditor.selection.getRng() 
        var $ = window.tinymce.get(id).dom.$;
    
        function getTextNode(cnf,num){
            let pDom = $(`${cnf.pTagName}[data-id="${cnf.pid}"]`)
            if(!pDom){
                resolve()
            }
             
            pDom = pDom[0] 
            let textNodes = []
            let txt = ''
            let textNode = null;
            function traverse(node) {
                if (node.nodeType === Node.TEXT_NODE) {
                    textNodes.push(node);  
                }  
                for (var i = 0; i < node.childNodes.length; i++) {
                    traverse(node.childNodes[i]);
                }
            } 
            traverse(pDom);
    
            textNodes.map(i=>{
                if(textNode)return;
    
                let afterTxt = txt + i.nodeValue 
    
                if(afterTxt.length >= cnf.offset + num){
                    textNode = {
                        node:i,
                        ...cnf,
                        offset:cnf.offset - txt.length//txt.length - cnf.offset - i.nodeValue.length //cnf.offset - txt.length + i.nodeValue.length
                    };
                }
                txt = afterTxt;
            }) 
            return textNode
        }
        let strts = getTextNode(startConfig,1)
        let end = getTextNode(endConfig ,0 )
        
        setTimeout(()=>{
            range.setStart(strts.node, strts.offset);
            try{
                range.setEnd(end.node , end.offset);
            }catch(err){ 
            }
            tinymce.activeEditor.selection.setRng(range)
            tinymce.activeEditor.execCommand('BackColor', false, color);  // 设置背景色为红色 
                resolve() 
                // 取消选区,但保留选中的内容
                tinymce.activeEditor.selection.collapse();
            // },400)
        },0)
    })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Web_Lys

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值