簡體   English   中英

JavaScript:刪除HTML標簽,修改標簽/文本並插入標簽

[英]JavaScript: Remove HTML Tags, Modify Tags/Text, and Insert Tags Back In

我試圖找到一種方法來刪除HTML文檔中的所有標簽,存儲它們的位置,修改剩余的文本,然后將標簽重新插入它們所屬的位置。

關鍵點

  • 我需要稍后再插入標簽,因此我需要存儲每個標簽的位置
    • 因此, 此處建議的DOMParser將不起作用
  • 這將在外部網站而不是我自己的網站上完成
  • 這里建議的正則表達式( /<(?:.|\\n)*?>/gm )可以工作,但它也會錯誤地捕獲<>包含在html中的
  • 看來這可行: https : //regexr.com/3npgn/<[^<|>]*>/g ),但我讀到使用regex並不是解析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);

為避免混淆,下面是我要完成的工作的詳細說明:在整個(外部)網站(不包括標簽)的文本中搜索字符串,如果找到,則更改這些實例的樣式(例如顏色) 。

那就是你應該做的:)

首先,構建一個遞歸函數以遍歷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);

而且...就是這樣! 為了獲得更多榮譽,以下是“撤消”搜索的方法:

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);

JSFiddle上的演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM