Der Code und die Funktionen wurden unter Chrome49 getestet und sind gültig.
Das Wesentliche beim Rendern von Text ist das Rendern von Textknoten. Der ausgewählte Startpunkt und Endpunkt kann über den integrierten Objektbereich des Browsers ermittelt werden
var range = getRangeObject();var start = range.startOffset, end = range.endOffset;var startContainer = range.startContainer;var endContainer = range.endContainer;
Der getRangeObjec-Code lautet wie folgt
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; };
Der Startpunkt liegt immer links und der Endpunkt immer rechts, unabhängig davon der gewählten Richtung.
Nur wenn der Anfang des Startpunkts oder das Ende des Endpunkts
ist, wird der Textknoten nicht zurückgegeben. Die Position des br-Elements kann durch start bestimmt werden und end bzw. startContainer.childNodes [start], endContainer.childNodes[end-1]. Der zurückgegebene Textknotenstart stellt die Startposition des Cursors relativ zum Starttextknoten dar, und Ende stellt die Endposition des Cursors relativ zum Endtextknoten dar.
Der Algorithmus zum Erhalten des nächsten Textknotens ist
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; }
// Die obige Funktion verwendet externe Variablen + While-Schleife, um die Rekursion zu ersetzen , Der zusätzliche Schutzmechanismus reduziert Missbrauch und potenzielle Fehler, die zu einem extrem schlechten Erlebnis führen.
Alle Textknoten zwischen dem Startknoten und dem Endknoten abrufen
function getTextNodes(startTextNode,endTextNode){ let textNodeArray = []; let node = startTextNode;while (true) { node = getNextTextNode(node);if(node == endTextNode){break; } textNodeArray.push(node); } return textNodeArray; }
Das obige ist der detaillierte Inhalt vonBeispielanalyse der Kernidee des H5-Editors. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!