https://ko.javascript.info/selection-range
위 주소의 글을 제가 알아야 되는 부분만 번역했습니다.
문서의 Selection 과 더불어<input /> 과 같은 폼 양식의 Selection도 다룬다.
JS는 기존의 Selection을 가져오고, 전체, 부분적으로 선택과 해제할 수 있다.
또한 문서에서 selected된 부분을 제거하고, 태그로 감싸는 등의 작업을 수행할 수 있다.
selection의 기본 개념은 range(range start와 range end의 ’경계 지점’ - boundary points의 쌍)이다.
각 지점(range start, range end)은 그 지점의 출발점으로부터의 relative offset을 가진 부모 DOM 노드로 표현된다.
부모 노드가 element node라면 offset은 자식의 숫자로 나타나고,
텍스트 노드라면 offset은 텍스트안의 위치로 나타난다.
무언가 select 해보자.
먼저 range 를 만들자. (생성자는 파라미터가 없다.)
let range = new Range();
이제 range.setStart(node, offset) 와 range.setEnd(node, offest) 을 사용해 selection의 경계 지점을 설정할 수 있다.
예제를 위한 HTML snippet이다.
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
text node에 더 집중하며 DOM 구조를 보자.

지금은 Example: <i>italic</i> 를 select 해보자. (text node를 포함하면) p태그의 0번째, 1번째 자식이다.

let range = new Range();
const p = document.getElementById('p');
range.setStart(p, 0);
range.setEnd(p, 2);
alert(range); // Example: <i>italic</i>
document.getSelection().addRange(range);
0과 1이 아니라 0과 2인 것은 노드와 노드의 ‘간격’, 텍스트 노드라면 글자와 글자 사이의 ‘간격’을 파라미터로 넣는다고 보면 이해가 쉽다.
p 태그는 총 4개의 자식을 갖고 있고, 노드와 노드 사이의 간격은 0 ~ 4인 것이다. Example 이라는 텍스트 노드의 왼쪽이 0, <b>bold</b> 의 오른쪽이 4인 것이다.
let range = new Range();
range.setStart(p.firstChild, 2);
range.setEnd(p.querySelector('b').firstChild, 3);
range 오브젝트는 이런 속성들이 있다.
startContainer, startOffset - 출발점의 node와 offsetendContainer, endOffset - 끝점의 node와 offsetcollapsed - boolean형으로 range의 start와 end가 같으면 true를 리턴한다. (start와 end가 같으므로 range 내용이 없다.)commonAncestorContainer - Range의 모든 노드의 가장 가까운 공통 조상이다.range의 메소드들은 설명을 생략한다. 이름만 봐도 사용법을 알 수 있고, 우리가 주의할 건 요소 노드인지, 텍스트 노드인지 주의하는 것뿐이다. (요소 노드의 offset은 건너뛸 요소 노드들이고, 텍스트 노드의 offset은 건너뛸 문자들이기 때문이다.)
setStart(node, offset)setStartBefore, setStartAftersetEnd(node, offset)setEndBefore, setEndAfterselectNode(node)selectNodeContents(node)collapse(toStart)cloneRangeselection은 이런 속성들이 있다.
일단 range와 비스무리하게 start와 end를 표헌한, ‘anchor’와 ‘focus’가 있다.
anchorNode – selection이 시작되는 지점anchorOffset – selection 시작점으로부터 anchorNode의 offsetfocusNode – selection이 끝나는 지점,focusOffset – selection 끝 지점으로부터 focusNode의 offset,isCollapsed – selection에 선택된게 아무것도 없거나 존재하지 않을 시 true를 리턴rangeCount – selection의 range 개수를 리턴한다. Firefox를 제외한 모든 브라우저가 최대 1을 가진다.메소드들은 생소한 것 빼고 설명을 생략한다.
range와 관련된 메소드들이다.
getRangeAt(i)addRange(range)removeRange(range)removeAllRanges()empty()range 의 메소드를 사용하지 않고 selection range를 직접 관리할 수 있는 메소드들이다.
collapse(node, offset) – 선택된 range를 node의 offset에서 시작하고 끝나는 새 range로 바꾼다.setPosition(node, offset) – collapse의 alias이다.collapseToStart()collapseToEnd()extend(node, offset) – node와 offset으로 selection의 focus를 옮긴다.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset) – 주어진 파라미터들로 selection range를 바꾼다. anchor와 focus 사이에 있는 노드들은 전부 다 선택된다.selectAllChildren(node)deleteFromDocument()containsNode(node, allowPartialContainment = false)