富文本编辑器表格跨列合并后样式错乱怎么办?
我在用Quill做表格编辑功能时,合并单元格后相邻列的宽度会错乱。比如用下面这段代码合并两列后,右边的单元格会挤到左边:
function mergeCells(start, end) {
const table = this.quill.getSelection().table;
table.mergeCells(start.row, start.column, end.row - start.row + 1, 'col');
this.quill.format('tableHeader', true);
}
已经尝试过手动设置colspan和width样式,但合并后其他单元格宽度还是自动塌陷。用Chrome开发者工具看DOM结构没问题,就是渲染显示不对,卡了两天了完全没头绪…
首先,问题出在合并操作后Quill没有正确更新表格的列宽约束。虽然DOM结构是对的,但浏览器渲染时还是按合并前的布局来分配宽度。
解决方案分三步走:
第一步,在合并前记录当前各列的实际宽度。这个很关键,因为合并后我们需要手动维持这个比例:
第二步,修改你的合并函数,合并后立即修复列宽。这里要注意合并操作是异步的,所以要等下一个tick:
第三步,处理合并后表格头部的特殊样式。你之前用的format('tableHeader')其实不太够,应该这样:
原理其实很简单:Quill的表格模块在合并单元格时,没有正确维护CSS的宽度约束。我们需要手动保存原始宽度,合并后重新应用,最后触发一次完整的表格重计算。
这里有两点要注意:
1. 必须用offsetWidth而不是style.width,因为用户可能通过拖拽改变了列宽
2. setTimeout是必须的,因为合并操作是异步的,直接同步操作DOM会拿不到最新状态
我之前也被这个问题折磨了很久,最后发现Quill的table模块源码里其实有_balanceTables方法,但没在合并操作后自动调用,就很迷...
你可以试试在合并操作完成后,强制刷新一下表格的布局。给你的代码加一段修正逻辑:
这里的
setTimeout是为了让样式更新延迟到DOM渲染完成之后。虽然不太优雅,但确实能解决问题。另外提醒一下,Quill的表格功能本身支持有限,如果需求复杂可能要考虑换更专业的富文本编辑器。希望能帮到你!