选择 span 元素时,Javascript Selection API::containsNode() 不会返回 true

标签 javascript selection selection-api

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

我不明白为什么我应该在图像之前和之后至少选择一个字符,以便 containsNodespan 元素上返回 true 。这是预期的行为吗?只要选择 img 就应该选择 span 元素,对吗?

最佳答案

这是预期的行为。

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

关于选择 span 元素时,Javascript Selection API::containsNode() 不会返回 true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66857182/

相关文章:

javascript - 如何单击图标并使用react,日期选择器将打开

javascript - $(this).is (':checkbox' ) 阻止检查

javascript - 为什么setSelectionRange不能在android 2.3平台浏览器上工作

javascript - 获取SelectionStart之前和SelectionEnd之后的所有文本

javascript - 非 textarea 元素的 selectionStart

javascript - 如何使用关联数组上的整数索引进行迭代?

javascript - Aurelia.js 在单击后插入 CSS 类并仅绑定(bind)单击的行

javascript - 从 JSON 中选择

javascript - 防止清除选择

jQuery 选择框替换