问题描述
我正试图找到一种方法来删除HTML文档中的所有标签,存储它们的位置,修改其余文本,然后将标签重新插入它们所属的位置.
I am trying to find a way to remove all tags in an HTML document, store their location, modify the remaining text, then reinsert the tags where they belong.
关键点
- 我需要稍后再插入标签,因此我需要存储每个标签的位置
- 因此,此处建议的DOMParser将不起作用
- I need to insert the tags back in again later, thus I need to store the location of each tag
- Therefore, DOMParser as suggested here will not work
完整代码:
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, ''); } }
编辑
为避免混淆,下面是我要完成的工作的详细说明:
EDIT
To avoid confusion, here follows a detailed explanation of what I want to accomplish:
在整个(外部)网站(不包括标签)的文本中搜索字符串,然后更改这些实例的样式(例如颜色).
Search for a string in the text of a whole (external) website (not including the tags), then change the styling (e.g. color) of those instances if found.
这是我的尝试:
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);
推荐答案
那正是您应该做的:)
首先,构建一个递归函数以遍历DOM并获取所有文本节点:
First, build a recursive function to traverse the DOM and get all the text nodes:
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);
现在您已经有了文档中所有文本节点的数组,您可以开始在它们中搜索目标.
Now that you have an array of all the text nodes in the document, you can begin searching them for your target.
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);
然后...就是这样!为了获得更多的荣誉,以下是撤消"搜索的方法:
And... that's it! For extra credit, here's how to "undo" the search:
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);
这篇关于JavaScript:删除HTML标签,修改标签/文本并插入标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!