In this chapter we’ll cover selection in the document, as well as selection in form fields, such as <input>.
JavaScript can access an existing selection, select/deselect DOM nodes as a whole or partially, remove the selected content from the document, wrap it into a tag, and so on.
You can find some recipes for common tasks at the end of the chapter, in “Summary” section. Maybe that covers your current needs, but you’ll get much more if you read the whole text.
The underlying Range and Selection objects are easy to grasp, and then you’ll need no recipes to make them do what you want.
Range
The basic concept of selection is Range, that is essentially a pair of “boundary points”: range start and range end.
A Range object is created without parameters:
let range = new Range();
Then we can set the selection boundaries using range.setStart(node, offset) and range.setEnd(node, offset).
The first argument node can be either a text node or an element node. The meaning of the second argument depends on that:
- If
nodeis a text node, thenoffsetmust be the position in the text. - If
nodeis an element node, thenoffsetmust be the child number.
For example, let’s create a range in this fragment:
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
Here’s its DOM structure:
Let’s make a range for "Example: <i>italic</i>".
As we can see, this phrase consists of exactly the first and the second children of <p>:
- The starting point has
<p>as the parentnode, and0as the offset. - The ending point also has
<p>as the parentnode, but2as the offset (it specifies the range up to, but not includingoffset).
Here’s the demo, if you run it, you can see that the text gets selected:
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range();
range.setStart(p, 0);
range.setEnd(p, 2);
// toString of a range returns its content as text, without tags
console.log(range); // Example: italic
// let's apply this range for document selection (explained later)
document.getSelection().addRange(range);
</script>
Here’s a more flexible test stand where you try more variants:
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
From <input id="start" type="number" value=1> – To <input id="end" type="number" value=4>
<button id="button">Click to select</button>
<script>
button.onclick = () => {
let range = new Range();
range.setStart(p, start.value);
range.setEnd(p, end.value);
// apply the selection, explained later
document.getSelection().removeAllRanges();
document.getSelection().addRange(range);
};
</script>