Reputation: 31455
I was wondering what is the main difference of purposes between the Selection API and the Range API.
From the snippet below, we can see that they are somehow interconnected. When you set one, you are automatically setting properties on the other. Even some of their methods are very similar.
// 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();
}
QUESTION
What is the main difference between the Selection API and the 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>
Upvotes: 2
Views: 255
Reputation: 12647
A non-empty selection created by user input always contains a single range - the range in the selection represents what is selected on screen. But you can also create ranges programmatically that are independent of what appears on screen.
This means you can have multiple ranges but you'll only have a single selection (Firefox is the exception and is the only major browser to support multiple selections).
Unlike selections, a range also has no direction. With a selection, the anchor (where the selection starts) can come before or after the focus (where the selection ends), depending on the direction in which the user made the selection (left-to-right/top-to-bottom or right-to-left/bottom-to-top). But ranges do not take direction into account.
Upvotes: 0
Reputation: 3253
This line explains it all:
const range = selection.getRangeAt(0);
Selection can have several ranges. Ranges may be overlapped. Hence - range is a part of selection with its own API.
Upvotes: 2