jquery 在节点innerText中搜索匹配的字符串,并将匹配的字符串 Package 在innerHTML维护标记中

vuv7lop3  于 2023-06-05  发布在  jQuery
关注(0)|答案(1)|浏览(386)

我正在寻找一种方法来搜索一个节点的innerText匹配字符串。然后将匹配的文本 Package 在<span>中。
要求:

1 >该节点可能包含html标签,我希望这些标签在匹配的文本选择中保持。
2 >我还希望匹配文本区分大小写。

例如:

This is my <strong>content</strong> to search.

我想找到“我的内容搜索”
在跨度中匹配并包裹"my <strong>content</strong> to search",结果为:

This is <span>my <strong>content</strong> to search</span>.

这段代码只在一个节点中搜索一个完全匹配的节点,如果有html标签,则不匹配(因为这些是额外的子节点):

/* Prompt for search */
    var text = prompt("Search for:", "");
    if (text == null || text.length == 0) return;

    /* Remove highlighted results */
    var spans = document.getElementsByClassName("labnol");

    if (spans) {
        for (var i = 0; i < spans.length; i++) {
            spans[i].style.backgroundColor = "transparent";
        }
    }

    function searchWithinNode(node, te, len) {
        var pos, skip, spannode, middlebit, endbit, middleclone;

        skip = 0;
        if (node.nodeType == 3) {
            pos = node.data.indexOf(te);

            if (pos >= 0) {
                spannode = document.createElement("span");
                spannode.setAttribute("class", "labnol");
                spannode.style.backgroundColor = "yellow";
                middlebit = node.splitText(pos);
                endbit = middlebit.splitText(len);
                middleclone = middlebit.cloneNode(true);
                spannode.appendChild(middleclone);
                middlebit.parentNode.replaceChild(spannode, middlebit);
                skip = 1;
            }
        } else if (node.nodeType == 1 && node.childNodes && node.tagName.toUpperCase() != "SCRIPT" && node.tagName.toUpperCase != "STYLE") {
            for (var child = 0; child < node.childNodes.length; ++child) {
                child = child + searchWithinNode(node.childNodes[child], te, len);
            }
        }
        return skip;
    }
    searchWithinNode(document.body, text, text.length);
iyfjxgzm

iyfjxgzm1#

我不得不为类似的目的编写代码-为选定的文本着色。我不知道如何通过节点来实现这一点,所以我将此任务作为HTML的替代(当然,如果所选文本中有特殊功能,例如:鼠标移过等等,它将丢失)。
您可以根据自己的目的更改searchInHtml()函数:

function colorizeSelection(color) {
    var selectedText = getSelectionText();
    if (selectedText == '') {
        console.log('Nothing is selected.');
        return;
    }

    var q = window.getSelection();

    var selectionObject;
    if (q.anchorNode.innerHTML) {
        selectionObject = q.anchorNode;
    }
    else {
        selectionObject = q.anchorNode.parentNode;
    }

    if (color != undefined) {
        var tmp = selectionObject.innerHTML;
        tmp = tmp.replace(
            new RegExp('(' + selectedText.replace(/\(/g,'\\(').replace(/\)/g,'\\)').replace(/\//g,'\\/').replace(/\:/g,'\\:') + ')'),
            '<span class="colorized" style="background-color: ' + color +'">$1</span>'
        );
       
        if (tmp.length != selectionObject.innerHTML.length) {
            selectionObject.innerHTML = tmp;
        }
        else {
            console.log('Possible tags in the selection.');
            var matchingStr = searchInHtml(selectionObject.innerHTML, selectedText);
            selectionObject.innerHTML = selectionObject.innerHTML.replace(matchingStr,
                '<span class="colorized" style="background-color: ' + color +'">' + matchingStr + '</span>');
        }
    }
    else {
        // selectionObject.parentNode.innerHTML = selectionObject.parentNode.innerHTML.replace(
        //     new RegExp('<span class="colorized" style="background-color: .*?">(.*?)</span>'),
        //     '$1'
        // );
        q.baseNode.parentNode.style.backgroundColor = null;
    }

    function searchInHtml(html, text) {
        var splitted = splitHtml(html);
        var resultStr = '';

        var textOnly = '';
        for (var i = 0; i < splitted.length; i++) {
            if (!splitted[i].startsWith('<')) {
                textOnly += splitted[i];
            }
        }

        var start = textOnly.indexOf(text);

        if (start >= 0) {
            var startTmp = 0;
            var length = 0;

            for (var i = 0; i < splitted.length; i++) {
                if (splitted[i].startsWith('<')) {
                    if (resultStr == '') {
                        continue;
                    }
                    else {
                        resultStr += splitted[i];
                    }
                }
                else {
                    if (resultStr.length == 0) {
                        startTmp += splitted[i].length;
                        if (start >= startTmp) {
                            continue;
                        }
                        var substrLength = Math.min(startTmp - start, text.length);
                        resultStr = text.substr(0, substrLength);
                        length = substrLength;
                    }
                    else {                    
                        var substrLength = Math.min(splitted[i].length, text.length - length);
                        resultStr += splitted[i].substr(0, substrLength);
                        length += substrLength;
                    }
                }

                if (length == text.length) {
                    break;
                }
            }
        }

        return resultStr;

        function splitHtml(html) {
            var splitted = [];

            while (html.length > 0) {
                var toPosition = 0;
                if (html[0] == '<') {
                    toPosition = html.indexOf('>');
                }
                else {
                    toPosition = html.indexOf('<') - 1;
                }

                if (toPosition <= -1) {
                    toPosition = html.length;
                }

                splitted.push(html.substring(0, toPosition + 1));
                html = html.substr(toPosition + 1);
            }

            return splitted;
        }
    }

    function getSelectionText() {
        var text = "";
        if (window.getSelection) {
            text = window.getSelection().toString();
        } else if (document.selection && document.selection.type != "Control") {
            text = document.selection.createRange().text;
        }
        return text;
    }
}

相关问题