首页 > 解决方案 > 选择 span 元素时,Javascript 选择 API :: containsNode() 不返回 true

问题描述

我的问题是关于这个功能: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 元素,对吗?truespanimg

标签: javascriptselectionselection-api

解决方案


这是预期的行为。

来自Selection API 的规范

containsNode()方法

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

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

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

的接口定义containsNode()为:

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

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

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>

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


推荐阅读