如何让quill-better-table在Quill只读模式下完全不可编辑
quill-better-table 全局readOnly配置不生效解决方案
quill-better-table 内部没有绑定Quill根实例的readOnly状态,单元格编辑事件、右键操作菜单都是独立绑定的,所以全局只读配置不会自动作用到表格区域,可按以下方案修复:
方案1:动态切换场景首选,主动管控模块状态+事件拦截
适合需要在编辑/只读状态间动态切换的场景,覆盖所有交互场景:
- 封装统一的状态切换方法,切换只读时除了调用Quill原生的
enable方法,还要额外处理表格模块:
// 右键菜单拦截通用方法 function blockTableContextMenu(e) { if (e.target.closest('.quill-better-table-wrapper td')) { e.preventDefault(); e.stopPropagation(); } } /** * 切换Quill编辑器只读状态 * @param {Quill} quillInstance Quill实例 * @param {boolean} isReadOnly 是否只读 */ function setEditorReadOnly(quillInstance, isReadOnly) { // 原生只读配置生效 quillInstance.enable(!isReadOnly); const betterTableModule = quillInstance.getModule('better-table'); const editorRoot = quillInstance.root; if (isReadOnly) { // 隐藏表格内置工具栏 betterTableModule.hideTableTools(); // 所有现有单元格设为不可编辑 editorRoot.querySelectorAll('.quill-better-table-wrapper td').forEach(cell => { cell.setAttribute('contenteditable', 'false'); }); // 拦截表格区域右键,阻止操作菜单唤起 editorRoot.addEventListener('contextmenu', blockTableContextMenu, true); // 兜底隐藏已生成的操作菜单节点 const menuNode = document.querySelector('.quill-better-table-operation-menu'); if (menuNode) menuNode.style.display = 'none'; } else { // 恢复编辑状态 editorRoot.querySelectorAll('.quill-better-table-wrapper td').forEach(cell => { cell.setAttribute('contenteditable', 'true'); }); editorRoot.removeEventListener('contextmenu', blockTableContextMenu, true); } }
- 动态插入表格后补做状态校验,避免新插入的表格不受控,修改原表格插入方法:
addCreateTableBtnEvent: function () { const tableModule = quill.getModule('better-table'); tableModule.insertTable(2, 2); // 插入后如果当前是只读状态,立刻给新表格加禁用逻辑 if (this.readOnly) { setTimeout(() => setEditorReadOnly(quill, true), 0); } }
方案2:固定只读场景首选,初始化时直接屏蔽模块交互
如果编辑器初始化后就固定为只读状态,不需要动态切换,可直接在配置层关闭菜单能力,减少运行时事件监听:
const quill = new Quill('#editor-wrapper', { theme: 'snow', readOnly: this.readOnly || false, modules: { table: false, 'better-table': { operationMenu: { // 清空所有菜单项,即使菜单异常唤起也无可操作内容 items: {} }, toolbar: { container: [['tableCreate']], handlers: { 'tableCreate': () => this.addCreateTableBtnEvent() } }, } } }) // 初始化完成后拦截表格区域右键 if (this.readOnly) { quill.root.addEventListener('contextmenu', blockTableContextMenu, true); }
兜底辅助方案:CSS层面屏蔽交互
可搭配以上任意方案使用,加一层样式兜底,避免极端场景下交互漏拦截:
/* 只读状态下给ql-editor加is-readonly类即可生效 */ .ql-editor.is-readonly .quill-better-table-wrapper td { pointer-events: none; /* 如需保留文本选中复制能力,保留下面这行,不需要就设为none */ user-select: text; } .ql-editor.is-readonly .quill-better-table-operation-menu, .ql-editor.is-readonly .quill-better-table-tools { display: none !important; }
内容的提问来源于stack exchange,提问作者Ellen
相关产品推荐
相关产品推荐

