코드와 기능은 chrome49에서 테스트되었으며 유효합니다.
텍스트 렌더링의 본질은 텍스트 노드의 렌더링입니다. 선택한 시작점과 끝점은 브라우저의 내장 객체 범위를 통해 얻을 수 있습니다
var range = getRangeObject();var start = range.startOffset, end = range.endOffset;var startContainer = range.startContainer;var endContainer = range.endContainer;
getRangeObjec 코드는 다음과 같습니다
function getRangeObject(){if(window.getSelection) {var selection = window.getSelection();if(selection.rangeCount > 0) {return selection.getRangeAt(0); } }else if(document.selection) {return document.selection.createRange(); }return null; };
시작점은 항상 왼쪽, 끝점은 선택한 방향에 상관없이 항상 오른쪽입니다.
시작점의 시작이나 끝점의 끝이
인 경우에만 텍스트 노드가 반환되지 않습니다. br 요소의 위치는 각각 startContainer와 end로 결정될 수 있습니다. childNodes[시작], endContainer.childNodes[end-1]. 반환된 텍스트 노드 start는 시작 텍스트 노드를 기준으로 커서의 시작 위치를 나타내고, end는 종료 텍스트 노드를 기준으로 커서의 끝 위치를 나타냅니다.
다음 텍스트 노드를 얻기 위한 알고리즘은
function getNextTextNode(startNode,dir = "nextSibling"){//记录startNode变化之前的状态,startNode变化后无效时便于状态的回滚let unchangeNode = startNode;if(startNode.nodeType == 3){ startNode = startNode[dir]; }while (true){if(startNode == undefined){if(unchangeNode == undefined){//保护机制throw new Error("程序会陷入死循环");break; }/*startNode所在的父元素所有选中节点遍历完毕,将sartNode指向父元素的兄弟节点*/let parent = unchangeNode.parentElement; unchangeNode = parent; startNode = parent[dir]; }else if(startNode.nodeType == 3){//文本节点则退出循环break; }else if(startNode.tagName == "BR"){//处理单标签,避免不必要的迭代unchangeNode = startNode; startNode = startNode[dir]; }else if(startNode.nodeType == 1){/*如果是双标签元素则进入*/unchangeNode = startNode;if(dir == "previousSibling"){ startNode = $(startNode).contents().last().get(0); }else if(dir == "nextSibling"){ startNode = $(startNode).contents().first().get(0); }else {//便于错误的定位throw new Error("错误的遍历方向:"+dir); } }else {//便于错误的定位throw new Error("不期待的元素类型=》"+startNode); } } return startNode; }
입니다. //위 함수는 재귀를 대체하기 위해 외부 변수 + while 루프를 사용하며 추가된 보호 메커니즘은 오용, 잠재적인 버그 및 극도로 열악한 경험을 줄입니다.
시작 노드와 끝 노드 사이의 모든 텍스트 노드 가져오기
function getTextNodes(startTextNode,endTextNode){ let textNodeArray = []; let node = startTextNode;while (true) { node = getNextTextNode(node);if(node == endTextNode){break; } textNodeArray.push(node); } return textNodeArray; }
위 내용은 H5 에디터의 핵심 아이디어 예시 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!