quill富文本编辑器获取光标所在innerHTML索引

需求背景
做一个富文本编辑器,只保留有序列表,无序列表,超链接,普通文本四种形式。
1.quill配置toolbar保留四种形式的工具栏
2.此外,还要防止粘贴时出现不允许的数据格式

解决办法
监听paste粘贴事件,阻断粘贴默认行为,拿到剪切板的值,清洗掉不需要的标签和属性后,自行插入到innerHTML

难点
在自行插入时我们需要知道插入的位置,但是我们的quill或者web api只给我们提供了纯文本的光标索引, 例如光标在input里面选择了某个位置,那么可以在input的onclick回调通过event.tartget.selectionStart获取光标在innerText的索引,如下

<input type="text" id="txt1" value="你好1 你好2 你好3" onclick="getTextCursorIndex()" />
	function getTextCursorIndex (){
		const txt1 = document.getElementById("txt1");
	    let cursurPosition = -1;
	    if (txt1.selectionStart) {//非IE浏览器
	    	cursurPosition = txt1.selectionStart;
	    } else {//IE
	    	const range = document.selection.createRange();
	    	range.moveStart("character",-txt1.value.length);
	    	cursurPosition=range.text.length;
	   	}
		console.log(`innerText:${txt1.value}`)
		console.log(`光标所在innerText索引:${cursurPosition}`)
	}

在这里插入图片描述
但是我们无法获取到光标所在总innerHTML的索引,因为计算innerHTML位置的成本较高,所以我们放弃这种方式。
在这里插入图片描述
我们的innerText可能是这样的

"你好1 你好2 你好3"

对应的innerHTML是这样的

  <p>你好1</p>
  <ul>
    <li>你好2</li>
    <li>你好3</li>
  </ul>

我想到的做法是在光标具体所在富文本的dom中通过innerHTML的方式添加,啥意思呢?
就是说,咱们之前是在总innerHTML上修改粘贴值,但是这个位置算不出来

const html = quillDOM.innerHTML
quillDOM.innerHTML = `${html.slice(0, pointerIndex)}${e.clipboardData.getData("text/plain")}${html.slice(pointerIndex)}`

现在我们换一种思路,进到最深层具体的dom里面(这个元素底下没有子元素,子标签),那他的innerText的光标位置不就是innerHTML的光标位置吗,那我们不就可以直接用selectionStart插入了?

当你尝试过后,你会发现,只有input标签才能用event.target.selectionStart获取光标位置,普通的p标签或者其他都不能,哈哈,懵了吧,我自己研究了一个方法算具体的位置

那么如何获取最里层元素innerText的光标索引呢
1.通过在外层quill事件委托定位到被点击的dom元素, click事件
2.如下图,主要是通过计算差值和递归得出正解
在这里插入图片描述

     quillDOM.root.addEventListener('click', (e) => {
        let tmpIndex1 = quillDOM.selection.savedRange.index // 总字符串光标所处位置
        let eText = e.target.innerText 
        let quillDOMText = quillDOM.root.innerText
        let tmpIndex2 = quillDOMText.indexOf(eText) // 点击的元素的文本在总字符串的起始索引
        // 如果这里不做判断,那么之前如果有相同的innerText,会导致位置错误
        while (tmpIndex1 - tmpIndex2 > eText.length) {
            tmpIndex2 = quillDOMText.indexOf(eText, tmpIndex2)
        }
        pointerIndex = tmpIndex1 - tmpIndex2
    })
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Feng Wuqian

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

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

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

打赏作者

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

抵扣说明:

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

余额充值