You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quill BlockEmbed内嵌可编辑span的input事件未触发问题排查

问题分析与解决思路

你的问题核心在于Quill的BlockEmbed默认是不可编辑的嵌入块,Quill会在编辑器层面拦截这类元素上的所有编辑相关事件(包括input),以保证嵌入块内容的不可修改性,所以你绑定在span上的input事件根本无法触发。

以下是具体的解决思路和修改方案:


解决思路1:解除BlockEmbed的不可编辑限制

BlockEmbed继承自Embed,而Embed的默认contenteditable属性为false,Quill会将这类元素标记为「不可编辑区域」,并在事件冒泡阶段阻止编辑事件传递。你需要:

  1. 给BlockEmbed的根节点设置contenteditable="true",让Quill将其视为可编辑区域
  2. 改用捕获阶段绑定事件(将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 02:22:38