【问题标题】:Quill editor inside Shadow DOMShadow DOM 中的 Quill 编辑器
【发布时间】:2022-02-17 06:48:52
【问题描述】:
在本例中,编辑器是在 Shadow Root 中创建的。
https://codepen.io/artemiusgreat/pen/XWMPdWG
目前的主要问题是当从工具栏模块通过单击面板上的Bold 或Italic 按钮启动时,内联格式不起作用。
原因是window.getSelection 总是在 Shadow Root 内返回空选择。
好消息是,当通过按 CTRL+B 或 CTRL+我。
我正在深入研究代码,但如果有人已经解决了这个问题,我将不胜感激。
【问题讨论】:
标签:
javascript
quill
ngx-quill
【解决方案1】:
完成。
This fix 不包括 Safari 中缺少的shadow.getSelection,但所有其他浏览器都应该可以工作。就我而言,我只需要 Chrome。
var quill = new Quill(editorControl, {
modules: {
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline'],
['image', 'code-block']
]
},
placeholder: 'Compose an epic...',
theme: 'snow'
});
const normalizeNative = (nativeRange) => {
// document.getSelection model has properties startContainer and endContainer
// shadow.getSelection model has baseNode and focusNode
// Unify formats to always look like document.getSelection
if (nativeRange) {
const range = nativeRange;
if (range.baseNode) {
range.startContainer = nativeRange.baseNode;
range.endContainer = nativeRange.focusNode;
range.startOffset = nativeRange.baseOffset;
range.endOffset = nativeRange.focusOffset;
if (range.endOffset < range.startOffset) {
range.startContainer = nativeRange.focusNode;
range.endContainer = nativeRange.baseNode;
range.startOffset = nativeRange.focusOffset;
range.endOffset = nativeRange.baseOffset;
}
}
if (range.startContainer) {
return {
start: { node: range.startContainer, offset: range.startOffset },
end: { node: range.endContainer, offset: range.endOffset },
native: range
};
}
}
return null
};
// Hack Quill and replace document.getSelection with shadow.getSelection
quill.selection.getNativeRange = () => {
const dom = quill.root.getRootNode();
const selection = dom.getSelection();
const range = normalizeNative(selection);
return range;
};
// Subscribe to selection change separately,
// because emitter in Quill doesn't catch this event in Shadow DOM
document.addEventListener("selectionchange", (...args) => {
// Update selection and some other properties
quill.selection.update()
});
【解决方案2】:
我刚刚在我的 WebComponent 中实现了一个不错的方法 - 在 ShadowDOM 中使用 iframe 标记,并使用 Quill 加载另一个 HTML 页面。