1

我想知道选择 API 和范围 API 之间的主要用途区别是什么。

从下面的片段中,我们可以看到它们以某种方式相互关联。当您设置一个时,您会自动设置另一个属性。甚至他们的一些方法也非常相似。

// Select text from 0-5 using the Selection API
function onClick1() {
  root.focus();
  const selection = window.getSelection();
  selection.setBaseAndExtent(root.childNodes[0],0,root.childNodes[0],5);
  getSelectionInfo();
}
// Select text from 7 to 9 using the Range API
function onClick2() {
  root.focus();
  const selection = window.getSelection();
  const range = selection.getRangeAt(0);
  range.setStart(root.childNodes[0],6);
  range.setEnd(root.childNodes[0],9);
  getSelectionInfo();
}

问题

Selection API 和 Range API 之间的主要区别是什么?

const root = document.getElementById('root');
const infoP = document.getElementById('info');

function onClick1() {
  root.focus();
  const selection = window.getSelection();
  selection.setBaseAndExtent(root.childNodes[0],0,root.childNodes[0],5);
  getSelectionInfo();
}

function reset() {
  const selection = window.getSelection();
  selection.removeAllRanges();
  infoP.innerHTML = '';
}

function onClick2() {
  root.focus();
  const selection = window.getSelection();
  const range = selection.getRangeAt(0);
  range.setStart(root.childNodes[0],6);
  range.setEnd(root.childNodes[0],9);
  getSelectionInfo();
}

function getSelectionInfo() {
  const selection = window.getSelection();
  const range = selection.getRangeAt(0);
  const text = `
    <b>selection.anchorNode:</b> ${selection.anchorNode}
    <b>selection.anchorOffset:</b> ${selection.anchorOffset}
    <b>selection.focusNode:</b> ${selection.focusNode}
    <b>selection.focusOffset:</b> ${selection.focusOffset}
    <b>selection.isCollapsed:</b> ${selection.isCollapsed}
    <b>selection.rangeCount:</b> ${selection.rangeCount}
    <b>selection.type:</b> ${selection.type}\n
    <b>range.collapsed:</b> ${range.collapsed}
    <b>range.commonAncestorContainer:</b> ${range.commonAncestorContainer}
    <b>range.startContainer:</b> ${range.startContainer}
    <b>range.startOffset:</b> ${range.startOffset}
    <b>range.endContainer:</b> ${range.endContainer}
    <b>range.endOffset:</b> ${range.endOffset}
  `;
  infoP.innerHTML = text;
  
}
#root {
  border: 1px dotted blue;
}

#info {
  white-space: pre-wrap;
}
<div id="root" contenteditable>123456789</div>
<button onClick="onClick1()">Set Focus and Select 1-5 via Selection</button>
<button onClick="reset()">Reset</button>
<button onClick="onClick2()">Set Focus and Select 7-9 via Range</button>
<p><b>Selection info:</b></p>
<p id="info"></p>

4

2 回答 2

2

这一行解释了一切:

const range = selection.getRangeAt(0);

选择可以有多个范围。范围可能重叠。因此 - range 是具有自己 API 的选择的一部分。

于 2019-04-23T14:13:42.467 回答
0

由用户输入创建的非空选择始终包含一个范围 - 选择中的范围代表屏幕上选择的内容。但您也可以通过编程方式创建独立于屏幕上显示内容的范围。

这意味着您可以有多个范围,但您只能有一个选择(Firefox 是一个例外,并且是唯一支持多个选择的主要浏览器)。

与选择不同,范围也没有方向。通过选择,锚点(选择开始的位置)可以位于焦点(选择结束的位置)之前或之后,具体取决于用户进行选择的方向(从左到右/从上到下或从右到左/从下到上)。但是范围不考虑方向。

于 2021-06-11T00:02:15.853 回答