-
ContentEditable에서 커서(Caret) 활용하기(3) - 자바스크립트백수의 개발/웹 2020. 3. 4. 20:32
ContentEditable에서 커서(Caret) 활용하기(3) - 자바스크립트
[ ContentEditable에서 커서(Caret) 활용하기(2) - 자바스크립트 ]에서 Caret을 설정하고, 드래그의 형태로 만드는 것 까지 진행해봤다.
그러나 드래그의 형태로 해보면 알겠지만, 뒤에서 앞으로 드래그를 했을때와, 앞에서 뒤로 드래그를 했을 때는 엄연히 다를 것이다.
이번 글을 통해 이에 대해 알아보고 ContContentEditable에서 커서(Caret) 활용하기를 마무리 하겠다.
드래그 한 Caret의 위치
내가 키보드나 마우스로 Caret을 조정하였다면 큰 문제는 없을 것이다. 그런데 앞에서 한 것 처럼 Caret을 인위적으로 바꿨다면 나의 기준은 어디이고, 기준은 어떻게 바꿔야 할까?
아래와 같이 드래그가 되도록 Caret을 설정하였을 때 Shift + → 를 하면 어느방향으로 갈까?
아무런 설정 없이 Caret을 설정했다면, "아"로 부터 드래그가 움직일 것이다.
그렇다면 "다"로 부터 드래그가 움직이도록 기준을 바꾸는건 어떻게 해야할까?
이를 제대로 알기 위해서는 Selection에 대해 알아야한다. [ ContentEditable에서 커서(Caret) 활용하기(1) - 자바스크립트 ]에서도 Selection에 대해 작성하였지만, 크게 다루지 않았다. 여기서도 간단하게 알아보고 각각의 역할을 알아보자.
Selection{ anchorNode: node, anchorOffset: number, baseNode: node, baseOffset: number, extentNode: node, extentOffset: number, focusNode: node, focusOffset: number, isCollapsed: boolean, rangeCount: number, type: string }
그려진 caret의 형태만 봤을 때 anchor이 앞(시작점), focus가 뒤(끝지점)이라고 보면된다. 그래서 anchor가 focus보다 뒤에 있을 수 없다.
이와 비슷하게 base와 extent가 있는데 anchor/focus와 유사하지만 조금 다르다.
caret이 그려진다고 생각했을 때 base가 출발점, extent가 도착점으로 방향이 있다고 생각하면 된다.
그렇다면 우리는 어떻게 base와 extent를 설정할 수 있을지 알아보자.
[ ContentEditable에서 커서(Caret) 활용하기(2) - 자바스크립트 ]에서 caret을 설정한 것에서 base와 extent만 바꿔주면 된다.
아래의 코드를 통해 확인해보자. 위에 보여준 이미지를 바탕으로 "다"의 위치에서 caret이 움직을 수 있도록 수정해보자.
<div contenteditable='true'> <span>가나다</span><span>라마바사</span><span>아자차</span> <div>
const spanList = document.querySelectorAll("span"); // 각 span으로 부터 text node 가져오기 const startContainer = spanList[0].childNodes[0]; const startOffset = 2; const endContainer = spanList[2].childNodes[0]; const endOffset = 1; // Range 설정 const newRange = document.createRange(); newRange.setStart(startContainer, startOffset); newRange.setEnd(endContainer, endOffset); // Selection에 전달 const selection = document.getSelection(); selection.removeAllRanges(); selection.addRange(newRange); // Base와 Extent 교체 selection.setBaseAndExtent(selection.extentNode, selection.extentOffset, selection.baseNode, selection.baseOffset);
마지막에 있는 setBaseAndExtent를 통해 간단히 바꿔주어 아래 이미지 처럼 동작하게 할 수 있다.
테스트
간단히 테스트를 진행해보자.
setInterval(() => { const spanList = document.querySelectorAll("span"); // 각 span으로 부터 text node 가져오기 const startContainer = spanList[0].childNodes[0]; const startOffset = 2; const endContainer = spanList[2].childNodes[0]; const endOffset = 1; // Range 설정 const newRange = document.createRange(); newRange.setStart(startContainer, startOffset); newRange.setEnd(endContainer, endOffset); // Selection에 전달 const selection = document.getSelection(); selection.removeAllRanges(); selection.addRange(newRange); // Base와 Extent 교체 // 있을 때와 없을 때의 차이를 확인해보자. selection.setBaseAndExtent(selection.extentNode, selection.extentOffset, selection.baseNode, selection.baseOffset); }, 3000)
이런식으로 간단히 interval을 통해 3초마다 caret이 설정 된 후 Shift + ← or → 를 해보면 잘 작동하는지 확인할 수 있을 것이다.
'백수의 개발 > 웹' 카테고리의 다른 글
[ JavaScript ] 타입/클래스 비교 연산 Typeof/Instanceof (0) 2020.03.17 [CSS] box-sizing - element의 크기 정하기 (0) 2020.03.07 [ CSS ] margin vs padding - 여백 조정하기 (0) 2020.03.05 ContentEditable에서 커서(Caret) 활용하기(2) - 자바스크립트 (1) 2020.03.03 ContentEditable에서 커서(Caret) 활용하기(1) - 자바스크립트 (3) 2019.06.11