Quill BlockEmbed内嵌可编辑span的input事件未触发问题排查
问题分析与解决思路
你的问题核心在于Quill的BlockEmbed默认是不可编辑的嵌入块,Quill会在编辑器层面拦截这类元素上的所有编辑相关事件(包括input),以保证嵌入块内容的不可修改性,所以你绑定在span上的input事件根本无法触发。
以下是具体的解决思路和修改方案:
解决思路1:解除BlockEmbed的不可编辑限制
BlockEmbed继承自Embed,而Embed的默认contenteditable属性为false,Quill会将这类元素标记为「不可编辑区域」,并在事件冒泡阶段阻止编辑事件传递。你需要:
- 给BlockEmbed的根节点设置
contenteditable="true",让Quill将其视为可编辑区域 - 改用捕获阶段绑定事件(将
addEventListener的第三个参数设为true),绕过Quill在冒泡阶段的拦截
修改后的代码示例:
import Quill from 'quill'; const BlockEmbed = Quill.import('blots/block/embed'); class EditBlot extends BlockEmbed { static create(value) { const node = super.create(); // 关键:让BlockEmbed根节点可编辑,否则Quill会拦截子元素编辑事件 node.contentEditable = 'true'; const label = document.createElement('span'); label.innerText = value.text; node.appendChild(label); // 捕获阶段绑定input事件,避免被Quill在冒泡阶段拦截 label.addEventListener("input", () => { console.log('input触发'); value.text = label.innerText; const newValue = JSON.stringify(value); node.setAttribute('data-value', newValue); // 通知Quill更新内容,触发编辑器的change事件 Quill.find(node).quill.update(Quill.sources.USER); }, true); node.setAttribute('data-value', JSON.stringify(value)); return node; } static value(node) { return JSON.parse(node.getAttribute('data-value')); } } EditBlot.blotName = 'edit'; EditBlot.tagName = 'div'; Quill.register(EditBlot, true); export default EditBlot;
解决思路2:改用可编辑的Block作为基础Blot
如果你的业务场景不需要BlockEmbed的「不可嵌入内容」特性,直接继承Quill的Block blot(默认可编辑)会更简单,Quill不会拦截这类Block内子元素的编辑事件:
import Quill from 'quill'; const Block = Quill.import('blots/block'); class EditBlot extends Block { static create(value) { const node = super.create(); const label = document.createElement('span'); label.innerText = value.text; node.appendChild(label); label.addEventListener("input", () => { console.log('input触发'); value.text = label.innerText; node.setAttribute('data-value', JSON.stringify(value)); this.quill.update(Quill.sources.USER); }); node.setAttribute('data-value', JSON.stringify(value)); return node; } static value(node) { return JSON.parse(node.getAttribute('data-value')); } } EditBlot.blotName = 'edit'; EditBlot.tagName = 'div'; Quill.register(EditBlot, true); export default EditBlot;
注意事项
- 修改BlockEmbed的可编辑性后,需要确保Quill不会将你的自定义Blot误判为不可编辑区域,必要时可以重写
formats方法声明可编辑特性 - 每次修改内容后,调用
quill.update()通知Quill同步内容状态,否则编辑器的change事件不会触发,内容也无法正确保存
内容的提问来源于stack exchange,提问作者emorling
相关产品推荐
相关产品推荐

