在Tauri中使用Quill.js时,如何在quill.clipboard.addMatcher中处理异步?
在Tauri中使用Quill.js处理粘贴图片的异步本地化方案
Quill的clipboard.addMatcher回调是同步执行的,无法直接返回异步操作结果,这里提供两种可行的解决方案:
方案一:占位符+文本变更事件异步替换
先插入临时占位符,待后端返回本地URL后再替换占位符:
// 存储临时URL与对应异步处理Promise的映射 const pendingImages = new Map(); quill.clipboard.addMatcher('img', (node, delta) => { // 生成唯一临时URL作为占位符 const tempSrc = `temp://${Date.now()}-${Math.random().toString(36).slice(2)}`; // 缓存异步本地化任务 pendingImages.set(tempSrc, localize(node.src)); // 返回带占位符的Delta return new Delta().insert({ image: tempSrc }); }); // 监听文本变化,替换占位符为实际本地URL quill.on('text-change', async () => { const contents = quill.getContents(); let updateNeeded = false; for (const [index, op] of contents.ops.entries()) { const imgSrc = op.insert?.image; if (imgSrc?.startsWith('temp://')) { const promise = pendingImages.get(imgSrc); if (!promise) continue; updateNeeded = true; try { // 等待后端返回本地URL const localUrl = await promise; // 删除占位符并插入实际图片 quill.deleteText(index, 1); quill.insertEmbed(index, 'image', localUrl); } catch (err) { console.error('图片本地化失败:', err); // 失败时回退到原URL或删除占位符 quill.deleteText(index, 1); quill.insertEmbed(index, 'image', node.src); } finally { pendingImages.delete(imgSrc); } } } // 触发滚动更新确保内容渲染正确 if (updateNeeded) { setTimeout(() => quill.scroll.update(), 0); } }); async function localize(src) { if (src.startsWith('http')) { console.log(`${src} begins with http`); return invoke('localize', { src }); } // 非HTTP链接直接返回原地址 return src; }
方案二:拦截粘贴事件直接处理HTML内容
直接接管粘贴流程,先批量处理图片URL再插入编辑器:
// 监听Quill编辑器根节点的粘贴事件 quill.root.addEventListener('paste', async (e) => { e.preventDefault(); // 阻止默认粘贴行为 // 获取剪贴板中的HTML内容 const htmlContent = e.clipboardData.getData('text/html'); if (!htmlContent) return; // 创建临时DOM容器解析HTML const tempContainer = document.createElement('div'); tempContainer.innerHTML = htmlContent; // 批量处理所有图片 const imagePromises = Array.from(tempContainer.querySelectorAll('img')).map(async (img) => { if (img.src.startsWith('http')) { const localUrl = await invoke('localize', { src: img.src }); img.src = localUrl; } }); // 等待所有图片处理完成 await Promise.all(imagePromises); // 将处理后的HTML插入Quill编辑器 quill.clipboard.dangerouslyPasteHTML(tempContainer.innerHTML); });
方案对比
- 方案一:保留Quill默认的粘贴格式逻辑,仅替换图片URL,适合需要维持原有粘贴样式的场景。
- 方案二:完全控制粘贴流程,可自由修改HTML结构,适合需要自定义粘贴内容的场景。
内容的提问来源于stack exchange,提问作者yoyoLooming
相关产品推荐
相关产品推荐

