Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript:删除HTML标记,修改标记/文本,并将标记重新插入_Javascript_Html_Parsing - Fatal编程技术网

JavaScript:删除HTML标记,修改标记/文本,并将标记重新插入

JavaScript:删除HTML标记,修改标记/文本,并将标记重新插入,javascript,html,parsing,Javascript,Html,Parsing,我试图找到一种方法来删除HTML文档中的所有标记,存储它们的位置,修改剩余的文本,然后重新插入它们所属的标记 要点 我需要在以后再次插入标记,因此我需要存储每个标记的位置 因此,建议的DOMParser将不起作用 这将在外部网站上完成,而不是我自己的网站 建议的正则表达式(//gm)可以工作,但它也会错误地捕获html中包含的 例如: 这似乎是可行的:(/g),但我读到使用正则表达式不是解析html的好方法。有没有这样的情况会失败 完整代码: function foo() {

我试图找到一种方法来删除HTML文档中的所有标记,存储它们的位置,修改剩余的文本,然后重新插入它们所属的标记

要点

  • 我需要在以后再次插入标记,因此我需要存储每个标记的位置
    • 因此,建议的DOMParser将不起作用
  • 这将在外部网站上完成,而不是我自己的网站
  • 建议的正则表达式(
    //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, '');
    }
}
函数foo(){
var elementHtml=document.body.innerHTML;
var标签=[];
var标记位置=[];
//var htmlTagRegEx=/{1}/;
var htmlTagRegEx=/=0;i--){
var位置=标记位置[i];
如果(位置>文本结束位置){
位置+=highlightHTMLStart.length+HighlightHtmlLend.length;
}else if(位置>文本位置){
位置+=highlightHTMLStart.length;
}
elementHtml=elementHtml.substring(0,位置)+标记[i]+elementHtml.substring(位置);
}
}
//更新元素的html
document.body.innerHTML=elementHtml;
}
highlightInElement(document.documentElement,foointxt.value);
为了避免混淆,下面是我想要完成的详细说明:在整个(外部)网站(不包括标签)的文本中搜索字符串,然后更改这些实例的样式(例如颜色)

那么这正是你应该做的:)

首先,构建一个递归函数来遍历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);
函数findTextNodes(node,ret){
var c=node.childNodes,i,l=c.length;

对于(i=0;ii如果您修改文本,您将如何知道在何处重新插入标记?强制链接:@JeremyThille我正在保存标记的位置,因此只需根据该位置将其插入。这是第二个(不相关)代码的一部分,上面未显示。是否只替换或修改标记的文本部分?如果是,则可以使用元素节点。如果要将html标记放回,请使用
var htmlChunk=original.split('Brilliant!直接修改DOM,我没有想到。我唯一的问题是:remove函数剥离所有节点。有没有办法只删除我们实际插入的节点?我想我们可以在添加时将
span
节点保存在列表中。然后
replaceChild(span.firstChild,span)
?老实说,你最好使用一个更独特的类名。但是,是的,你可以保留一个插入节点的列表,然后在其上运行替换。我成功地完成了删除:)。如果可以的话,可以问几个后续问题:1)你说的唯一类名是什么意思?2)如果搜索词包含保留的正则字符([,,(,^等)3)如果我只想包含精确匹配(即搜索词不在另一个词中的匹配)会怎么样?我尝试了以下方法:
var searchString='(\\W|^)+search+'(\\W|$)
然后
var regex=new RegExp(searchString,'I');
(还记得更新
长度
参考,再往下一步)。它不起作用,你知道为什么吗?1)
会“更独特”,而且不太可能与其他东西发生冲突。2)你必须避免这些。通过一点重写,你可以使它与任意正则表达式一起工作,这很酷。3)在前后使用
\b
来指示单词边界。
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);
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);