需求
上一篇文章讲了如何使tinymce部分内容无法编辑,那么当然也有特殊需求是如何使部分内容无法删除啦。
思路
其实思路也比较简单,就是监听劫持键盘的按键事件,在按下delete或退格键时,判断即将删除的内容是否包含你设定的特殊标志字符,如果包含,则阻止删除事件生效就可以了。
当然,重点在于如歌获取即将删除的内容是关键,没有一个方法可已直接拿到按下删除键然后实际删除效果还未生效时即将删除的内容,所以,需要自己去根据实际情况不断地判断和操作。下面是我的实际场景的解决方法。
实际过程
监听键盘事件
首先,在初始化tinymce的过程中可以监听劫持键盘的按键事件,这个对聪明的大家肯定是小意思。代码如下
tinymce.init({// 其他配置项...setup: function(editor) {// 设置一个事件监听器,在键盘按键按下时触发editor.on('keydown', function(e) {if (e.keyCode === 46 || e.keyCode === 8) {// 阻止删除事件的发生e.preventDefault();// 在控制台输出提示信息console.log('删除事件已被阻止!')// 这里可以执行其他自定义操作// ...}});}});
e.keyCode === 46 和 e.keyCode === 8是键盘上Backspace和delete键的键码,keydown是当键按下时的事件,preventDefault()就是阻止事件的方法了。
获取即将删除的内容
这里包含两中情况,选中内容删除,和直接光标位置往前删除。
选中内容删除
当在编辑器中选中一部分删除时,这种情况非常简单,直接获取选中的内容,就是你按键后即将删除的内容了,代码如下
const selectedContent = editor.selection.getContent()
光标位置往前删除
如果没有选中任何内容,那么editor.selection.getContent()为空,但是我们可以发现,还是能够用editor.selection.getNode()获取到光标所在的节点,我们可以用节点进行一些逻辑判断,来达到我们的需求。
没有进行自定义dom操作的,一般tinymce编辑器中生成的标签是不含嵌套关系的(我说的是一般,图片、表格和代码块等特殊情况除外),那么,你用editor.selection.getNode()方法获取到的节点应该是当前行的节点,直接拿节点中的内容去判断是否包含你不让删除的特殊字符就行了。
但是对于图片,表格,代码块,或是跟我一样自定义了很多dom操作(在选中内容外层嵌套了一层div),这种情况下,必须要用当前节点加上父节点、子节点等综合判断来处理。特别注意的是,富文本编辑器行末会有br标签,不要被界面视觉效果迷惑,光标在同一个位置,但是有可能在标签内,也有可能在标签外,请实时查看你的html结构变化。
// 特殊处理节点内容if (editor.selection.getNode().outerHTML.indexOf('<br data-mce-bogus="1">') != -1) {if (editor.selection.getNode().previousSibling.outerHTML.indexOf('name=sample') != -1) {//阻止删除事件console.log('删除失败')e.preventDefault()}} else {if (editor.selection.getNode().outerHTML.indexOf('name=module-workitem') != -1) {//阻止删除事件console.log('删除失败')e.preventDefault()}}
我的业务需要是不能删除标签属性中包含“name=sample”的div,这div是我自己加进去的(如何操作上一篇文章有讲),所以其中有我增加的属性“name=sample”。所以我首先判断当前光标是在这个div中,还是在这个div后面的br标签中,如果在br中,则判断当前节点的前一个节点是否包含我的标识字符,如果不在br中,则判断当前节点是否包含标识字符。
每个特殊需求都是根据具体业务场景不同处理,仅供参考,有用的话点个赞。