我正在尝试找到一种方法来删除HTML文档中的所有标记,存储它们的位置,修改剩余的文本,然后将标记重新插入它们所属的位置。
要点
/<(?:.|\n)*?>/gm
)会起作用,但它也会错误地捕获包含html的<
或>
/<[^<|>]*>/g
),但我读到使用正则表达式并不是解析html的好方法。是否存在失败的情况?完整代码:
function foo() {
var elementHtml = document.body.innerHTML;
var tags = [];
var tagLocations = [];
//var htmlTagRegEx =/<{1}\/{0,1}\w+>{1}/;
var htmlTagRegEx =/<[^<]*>/;
//Strip the tags from the elementHtml and keep track of them
var htmlTag;
while (htmlTag = elementHtml.match(htmlTagRegEx)) {
console.log('htmlTag: ', htmlTag);
tagLocations[tagLocations.length] = elementHtml.search(htmlTagRegEx);
tags[tags.length] = htmlTag;
elementHtml = elementHtml.replace(htmlTag, '');
}
}
为避免混淆,下面详细解释我想要完成的事情:
在整个(外部)网站的文本中搜索字符串(不包括标签),然后更改这些实例的样式(例如颜色)。
这是我的尝试:
function highlightInElement(elementId, text) {
var elementHtml = document.body.innerHTML;
var tags = [];
var tagLocations = [];
//var htmlTagRegEx =/<{1}\/{0,1}\w+>{1}/;
var htmlTagRegEx =/<[^<]*>/;
//Strip the tags from the elementHtml and keep track of them
var htmlTag;
while (htmlTag = elementHtml.match(htmlTagRegEx)) {
//console.log('htmlTag: ', htmlTag);
tagLocations[tagLocations.length] = elementHtml.search(htmlTagRegEx);
tags[tags.length] = htmlTag;
elementHtml = elementHtml.replace(htmlTag, '');
}
console.log('elementHtml: ', elementHtml);
//Search for the text in the stripped html
var textLocation = elementHtml.search(text);
if (textLocation) {
//Add the highlight
var highlightHTMLStart = '<span class="highlight">';
var highlightHTMLEnd = '</span>';
elementHtml = elementHtml.replace(text, highlightHTMLStart + text + highlightHTMLEnd);
//plug back in the HTML tags
var textEndLocation = textLocation + text.length;
for (let i = tagLocations.length - 1; i >= 0; i--) {
var location = tagLocations[i];
if (location > textEndLocation) {
location += highlightHTMLStart.length + highlightHTMLEnd.length;
} else if (location > textLocation) {
location += highlightHTMLStart.length;
}
elementHtml = elementHtml.substring(0, location) + tags[i] + elementHtml.substring(location);
}
}
//Update the html of the element
document.body.innerHTML = elementHtml;
}
highlightInElement(document.documentElement, fooInputTxt.value);
答案 0 :(得分:2)
为了避免混淆,下面详细解释我想要完成的任务:在整个(外部)网站的文本中搜索字符串(不包括标签),然后更改那些的样式(例如颜色)如果找到实例。
那就是你应该做的事情:)
首先,构建一个递归函数来遍历DOM并获取所有文本节点:
function findTextNodes(node, ret) {
var c = node.childNodes, i, l = c.length;
for( i=0; i<l; i++) {
switch(c[i].nodeType) {
case 1: // element node
findTextNodes(c[i], ret);
break;
case 3: // text node
ret.push(c[i]);
break;
}
}
}
var textNodes = [];
findTextNodes(document.body, textNodes);
现在您拥有文档中所有文本节点的数组,您可以开始搜索它们以查找目标。
function searchTextNodes(nodes, search) {
var results = [], l = nodes.length, i,
regex = new RegExp(search,'i'), match,
span;
for( i=0; i<l; i++) {
while( (match = nodes[i].nodeValue.search(regex)) > -1) {
nodes[i] = nodes[i].splitText(match);
span = document.createElement('span');
span.classList.add('highlight');
nodes[i].parentNode.insertBefore(span, nodes[i]);
nodes[i].splitText(search.length);
span.appendChild(nodes[i]);
nodes[i] = span.nextSibling;
}
}
}
searchTextNodes(textNodes, fooInputTxt.value);
而且......那就是它!对于额外的信用,这里是如何&#34;撤消&#34;搜索:
function undoSearch(root) {
var nodes = root.querySelectorAll("span.highlight"),
l = nodes.length, i;
for( i=0; i<l; i++) {
nodes[i].parentNode.replaceChild(nodes[i].firstChild, nodes[i]);
}
root.normalize();
}
undoSearch(document.body);