JS에서 현재 선택한 텍스트를 아래 코드로 가져올 수 있다.
window.getSelection()
그러나 여기서 focusOffset
같은 경우는 글자 단위로 알려주기 때문에 아래(DeepL)와 같은 UI를 구성하기가 쉽지 않다.
여러 자료를 찾아보면 아래처럼 사용하는 걸 볼 수 있다.
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const rect = range.getClientRects();
그러나 이렇게 하게 되면 여러 줄을 드래그했을 때나 (오른쪽 -> 왼쪽) 방향으로 드래그 했을 때 원하는 위치의 좌표가 나오지 않는다. 😢
따라서 이 문제를 해결하기 위해서는 귀찮지만 방향을 측정하고 방향에 따라 함수를 다르게 구성해야한다.
const getIconPosition = () => {
const selection = window.getSelection();
if (selection && selection.rangeCount > 0 && !selection.isCollapsed) {
// 현재 선택한 범위
const range = selection.getRangeAt(0);
if (selection.focusNode) {
// 반대 방향 드래그 여부
const isBackward = selection.anchorNode === selection.focusNode
? selection.anchorOffset > selection.focusOffset
: selection.anchorNode?.compareDocumentPosition(selection.focusNode) === Node.DOCUMENT_POSITION_PRECEDING;
const rect = range.getClientRects()[isBackward ? 0 : range.getClientRects().length - 1];
return {
x: isBackward ? rect.left : rect.left + rect.width, // X 좌표
y: rect.top, // Y 좌표
};
}
} else {
return {
x: 0,
y: 0,
}
}
};
아래는 위와 같은 코드로 완성한 UI다.