Insert HTML into text node with JavaScript

后端 未结 5 1929
萌比男神i
萌比男神i 2020-12-05 13:59

I\'ve got a little text node:

var node

And I want to wrap a span around every occurrence of \"lol\".

node.nodeValue = node.         


        
5条回答
  •  时光取名叫无心
    2020-12-05 14:35

    The answer presented by Andreas Josas is quite good. However the code had several bugs when the search term appeared several times in the same text node. Here is the solution with those bugs fixed and additionally the insert is factored up into matchText for easier use and understanding. Now only the new tag is constructed in the callback and passed back to matchText by a return.

    Updated matchText function with bug fixes:

    var matchText = function(node, regex, callback, excludeElements) { 
    
        excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas']);
        var child = node.firstChild;
    
        while (child) {
            switch (child.nodeType) {
            case 1:
                if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1)
                    break;
                matchText(child, regex, callback, excludeElements);
                break;
            case 3:
                var bk = 0;
                child.data.replace(regex, function(all) {
                    var args = [].slice.call(arguments),
                        offset = args[args.length - 2],
                        newTextNode = child.splitText(offset+bk), tag;
                    bk -= child.data.length + all.length;
    
                    newTextNode.data = newTextNode.data.substr(all.length);
                    tag = callback.apply(window, [child].concat(args));
                    child.parentNode.insertBefore(tag, newTextNode);
                    child = newTextNode;
                });
                regex.lastIndex = 0;
                break;
            }
    
            child = child.nextSibling;
        }
    
        return node;
    };
    

    Usage:

    matchText(document.getElementsByTagName("article")[0], new RegExp("\\b" + searchTerm + "\\b", "g"), function(node, match, offset) {
        var span = document.createElement("span");
        span.className = "search-term";
        span.textContent = match;
        return span;
    });
    

    If you desire to insert anchor (link) tags instead of span tags, change the create element to be "a" instead of "span", add a line to add the href attribute to the tag, and add 'a' to the excludeElements list so that links will not be created inside links.

提交回复
热议问题