为啥`Selection.isCollapsed` 在影子 DOM 中总是正确的?
Posted
技术标签:
【中文标题】为啥`Selection.isCollapsed` 在影子 DOM 中总是正确的?【英文标题】:Why is `Selection.isCollapsed` always true in a shadow DOM?为什么`Selection.isCollapsed` 在影子 DOM 中总是正确的? 【发布时间】:2021-10-23 05:11:02 【问题描述】:根据MDN 和javascript.info,如果有任何当前选定的文本,Selection.isCollapsed
应该是false
。对于常规 DOM,这可以按预期工作,但对于影子 DOM,isCollapsed
似乎总是true
,即使当前选择了一些文本。有趣的是,在 shadow DOM 中调用 getSelection()
似乎确实正确地返回了当前选择——像 anchorNode
和 anchorOffset
这样的东西是正确的。但是isCollapsed
始终是true
,即使它应该是false
。
这是一个示例代码框(editor、web view),这是一个代码示例:
document.getElementById("app").innerhtml = "<h1>Hello DOM</h1>";
window.customElements.define(
"example-component",
class extends HTMLElement
constructor()
super();
const mountPoint = document.createElement("div");
this.attachShadow( mode: "open" );
mountPoint.innerHTML = `<h1>hello Shadow DOM</h1>`;
this.shadowRoot?.appendChild(mountPoint);
);
document.addEventListener("selectionchange", () =>
console.log("dom selectionchange");
console.log(window.getSelection());
console.log("shadow dom selectionchange");
console.log(
document.querySelector("example-component").shadowRoot.getSelection()
);
);
我使用的是 Chrome 92。
Selection API 和 shadow dom/web 组件似乎确实存在一些问题,但正如我所说,它似乎大部分都在工作,只是这个属性不正确。 p>
【问题讨论】:
【参考方案1】:所以问题在于 shadowRoot.getSelection()
不是标准 API,仅在基于 Chromium 的浏览器中受支持。并且document.getSelection()
不支持位于影子根内的选择。
目前正在进行扩展选择 API 以支持影子 DOM 的工作,您可以查看当前提案 in this comment 的摘要。如果该提案达成共识,Chrome 可能会弃用 shadowRoot.getSelection()
API,因为新的 selection.getComposedRange()
API 将取代它。
同时,此处 OP 中的行为似乎是 Chromium 中的一个错误:即使选择来自 shadowRoot.getSelection()
,isCollapsed
的值也来自 document.getSelection()
。我提交了bug for this。鉴于上述工作要进行替换,我不确定它是否会引起太多关注,但也许!
【讨论】:
非常感谢。在此处包含指向相关 caniuse 的链接:caniuse.com/mdn-api_shadowroot_getselection以上是关于为啥`Selection.isCollapsed` 在影子 DOM 中总是正确的?的主要内容,如果未能解决你的问题,请参考以下文章
为啥使用 glTranslatef?为啥不直接更改渲染坐标?
为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?