Javascript 选择 API :: containsNode() 在选择 span 元素时 return 不为真

Javascript Selection API :: containsNode() does not return true when span element is selected

我的问题是关于这个函数的: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);
});

我不明白为什么我应该 select 在图像前后至少一个字符所以 containsNode returns truespan元素。这是预期的行为吗?只要 img 被 selected,span 元素就应该被 selected,对吧?

这是预期的行为。

来自specification for the Selection API:

containsNode() method

The method must return false if the context object is empty or if node's root is not the document associated with the context object.

Otherwise, if allowPartialContainment is false, the method must return true if and only if start of its range is before or visually equivalent to the first boundary point in the node and end of its range is after or visually equivalent to the last boundary point in the node.

If allowPartialContainment is true, the method must return true if and only if start of its range is before or visually equivalent to the first boundary point in the node or end of its range is after or visually equivalent to the last boundary point in the node.

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 是一个空元素(没有内容),因此不能仅部分包含在选择中。