//nextTextNode is for getting the next text node from the DOM
function nextTextNode(node) {
if (node.nodeType == 1) { //element
while (node.nodeType != 3) {
node = node.firstChild;
}
return node;
}
if (node.nodeType == 3) { //text node
if (node.nextSibling) {
if (node.nextSibling.nodeType == 3) {
return node.nextSibling;
} else {
return nextTextNode(node.nextSibling);
}
} else {
while (!node.nextSibling) {
node = node.parentNode;
if (!node) return null;
}
if (node.nextSibling.nodeType == 3) {
return node.nextSibling;
} else {
return nextTextNode(node.nextSibling);
}
}
} else {
throw new Error("nextTextNode: Node is either null, not connected to the DOM, or is not of node type 1 or 3");
}
}
然后创建范围。与相比,文本节点具有额外的换行符和空格字符元素.innerText. 在下面的函数中,我跟踪额外字符数和总字符数,以跟踪innerText和node.node值有多少个“in”字。
function createRangeForString(startElement, text) {
var extras = 0;
var innerText = startElement.innerText;
var start = innerText.indexOf(text);
if (start === -1) throw new Error ("createRangeForString. text: " + text + " not found in startElement");
var textNode = nextTextNode(startElement);
var totalCharsSeen = 0;
var range = document.createRange();
for (var i = 0; i < start; i++) { // I don't think I have to add extras in limit for i. Is already included
if ((i + extras) - totalCharsSeen >= textNode.nodeValue.length) { //check if textNode is long enough
totalCharsSeen += textNode.nodeValue.length;
textNode = nextTextNode(textNode);
}
while (textNode.nodeValue.charAt(i + extras - totalCharsSeen) == "\n") {
extras++;
}
while (textNode.nodeValue.charAt(i + extras - totalCharsSeen) == " " && innerText.charAt(i) != " ") {
extras++;
}
}
range.setStart(textNode, i + extras - totalCharsSeen);
var end = start + text.length;
for (var i = start + 1; i < end; i++) { // I don't think I have to add extras in limit for i. Is already included
if ((i + extras) - totalCharsSeen >= textNode.nodeValue.length) { //check if textNode is long enough
totalCharsSeen += textNode.nodeValue.length;
textNode = nextTextNode(textNode);
}
while (textNode.nodeValue.charAt(i + extras - totalCharsSeen) == "\n") {
extras++;
}
while (textNode.nodeValue.charAt(i + extras - totalCharsSeen) == " " && innerText.charAt(i) != " ") {
extras++;
}
}
range.setEnd(textNode, i + extras - totalCharsSeen);
return range;
}