富文本协同编辑时如何解决光标错位问题?

令狐爱娜 阅读 11

我在用 Yjs + Quill 做富文本协同编辑,本地操作没问题,但多人同时编辑时,别人的光标经常跳到错误位置,甚至插入内容错乱。

我试过监听 selection-change 事件同步光标,也用了 Y.Text 的 observe 来更新内容,但光标位置还是对不上。是不是我的同步逻辑有问题?

这是我的光标同步代码:

provider.on('synced', () => {
  const yText = ydoc.getText('content');
  const quill = new Quill('#editor', { theme: 'snow' });
  
  // 绑定 Yjs 和 Quill
  const binding = new QuillBinding(yText, quill, provider.awareness);
  
  // 手动监听 selection(不确定是否多余)
  quill.on('selection-change', (range) => {
    if (range) {
      provider.awareness.setLocalStateField('cursor', {
        anchor: range.index,
        focus: range.length
      });
    }
  });
});
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
❤振莉
❤振莉 Lv1
试试这个:你把 QuillBindingselection-change 的顺序搞反了,而且 focus: range.length 写错了,应该是 focus: range.index + range.length。另外 QuillBinding 要在 ydoc 初始化之后、provider.connect() 之前就创建好,别等 synced 再建。正确流程是:

先初始化 ydoc 和 awareness,然后创建 quill 实例,再创建 binding,最后才监听 selection-change 并同步:

const ydoc = new Y.Doc();
const yText = ydoc.getText('content');
const provider = new WebsocketProvider('wss://...', 'room', ydoc);
const awareness = provider.awareness;

const quill = new Quill('#editor', { theme: 'snow' });
const binding = new QuillBinding(yText, quill, awareness);

quill.on('selection-change', (range) => {
if (range) {
awareness.setLocalStateField('cursor', {
index: range.index,
length: range.length
});
} else {
awareness.setLocalStateField('cursor', null);
}
});


还有注意:别在每次 synced 里重复创建 binding 和 quill,那是致命错误,会把之前的所有状态冲掉。
点赞 3
2026-02-25 21:04