【问题标题】:Javascript Selection API :: containsNode() does not return true when span element is selected选择跨度元素时,Javascript 选择 API :: containsNode() 不返回 true
【发布时间】:2021-06-12 08:55:31
【问题描述】:

我的问题是关于这个功能:https://developer.mozilla.org/en-US/docs/Web/API/Selection/containsNode 我已经创建了这个沙箱:https://codesandbox.io/s/amazing-bartik-smjt2?file=/src/index.js

代码:

document.getElementById("app").innerHTML = `
<h1>Hello Vanilla!</h1>
<div>
  We use the same configuration.<s> <span id="_span"><img src="http://www.mandysam.com/img/random.jpg" id="_img" alt="????" aria-label="????" width="40"></span> as Parcel to bundle this </s> sandbox, you can find more
  info about Parcel.
  <h2 id="y" hidden=true>span selected</h2>
  <h2 id="z" hidden=true>img selected</h2>
</div>
`;

document.addEventListener("selectionchange", () => {
  const selection = window.getSelection();

  let span = document.querySelector("#_span");
  const foundSpan = selection.containsNode(span);

  let img = document.querySelector("#_img");
  const foundImg = selection.containsNode(img);

  let y = document.querySelector("#y");
  y.toggleAttribute("hidden", !foundSpan);
  let z = document.querySelector("#z");
  z.toggleAttribute("hidden", !foundImg);
});

我不明白为什么我应该在图像前后至少选择一个字符,所以containsNode 在span 元素上返回true。这是预期的行为吗? the span element supposed to be selected whenever the img is selected, right?

【问题讨论】:

  • 请edit您的问题在问题本身中包含所有相关代码,而不仅仅是在像codesandbox.io这样的外部网站上。请阅读How to Ask。
  • 你好,亚历克斯!请花一些时间edit您的问题并访问How to Ask或访问Help Center。

标签: javascript selection selection-api


【解决方案1】:

这是预期的行为。

来自specification for the Selection API:

containsNode() 方法

如果上下文,该方法必须返回false 对象为空或者如果节点的根不是与关联的文档 上下文对象。

否则,如果allowPartialContainment是false,则该方法必须返回 true 当且仅当其范围的开始在之前或视觉上 相当于节点和的第一个边界点 范围在最后一个边界点之后或视觉上等同于 节点。

如果allowPartialContainment 是true,则该方法必须返回true,如果并且 仅当其范围的开始在之前或视觉上等同于 节点中的第一个边界点或其范围的末尾在或之后 视觉上等同于节点中的最后一个边界点。

containsNode() 的接口是defined as:

boolean containsNode(Node node, optional boolean allowPartialContainment = false);

如果您还希望仅部分包含的节点被视为选择的一部分,则必须为 allowPartialContainment 参数提供 true:

const foundSpan = selection.containsNode(span, true); 

document.addEventListener("selectionchange", () => {
  const selection = window.getSelection();

  let span = document.querySelector("#_span");
  const isFullyContained = selection.containsNode(span);
  const isPartiallyContained = selection.containsNode(span, true);

  let y = document.querySelector("#y");
  y.toggleAttribute("hidden", !isPartiallyContained || isFullyContained);
  let z = document.querySelector("#z");
  z.toggleAttribute("hidden", !isFullyContained);
});
<h1>Select the text with the image</h1>
<div>
  We use the same configuration.
  <span id="_span"><img src="http://www.mandysam.com/img/random.jpg" width="40"></span>
  as Parcel to bundle this sandbox, you can find more info about Parcel.
  <h2 id="y" hidden=true>span partially contained</h2>
  <h2 id="z" hidden=true>span fully contained</h2>
</div>

它适用于图像,因为 img 是一个 void 元素(没有内容),因此不能仅部分包含在选择中。

【讨论】:

  • help.dottoro.com/ljphmtlx.php 还在他们的页面上展示了这个概念的演示。
  • 感谢您的意见,我已经考虑过了。我将尝试改写我的问题,如果清楚,请告诉我:跨度仅包含 img 元素。 Why when the img element is selected the selection.containsNode(span) returns false and it only returns true when the selections includes at least 1 character before and after the span?
  • 这是因为边界点的定义方式。它们是节点的元组和该节点内选定元素的偏移量。所选图像的边界点是(span, 0) 和(span, 1),它们都在span 内。
  • 感谢我正在寻找的东西。可以分享边界点的链接吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 2017-09-22
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多