如何用HTML标签包装文本,但排除某些HTML标签内的文本

How to wrap text with HTML tags but exclude text inside certain HTML tags

本文关键字:文本 HTML 标签 排除 何用 包装      更新时间:2023-09-26

我正在创建一些函数来突出显示页面上的单词。这将在给定的单词周围包装span标记。我已经完成了这个任务,但我会再解释一点。

代码的工作方式是在页面首次加载时获取innerHTML,并将其存储在内存中(因此我有原始内容的副本)。

然后我取innerHTML(称为copyInnerHtml)的副本-然后我在copyInnerHtml上找到搜索词,并将它们与<span id="find-iteration">(其中迭代是唯一的数字,例如find-0, find-1, find-2等)标签包装,并将页面的内容替换为copyInnerHtml。然后,当用户重新点击搜索按钮时,我首先将页面恢复到原始的innerHTML内容,然后继续如上所述。这很有效。

如何找到文本(网站副本)只有文字和备注文字在HTML元素/属性中用作值。

示例:考虑以下代码
 <div class="search">This is the search box</div>

现在,我想执行搜索单词"search"。问题是,它会找到它两次。

不使用正则表达式,只使用JavaScript(没有jQuery请),我怎么能检测字符串是否是HTML标签的一部分?

这个JSFIDDLE应该会让我所做的事情更清楚

现在,您可能会注意到小提琴

中的以下行
<p class="changeMe">&nbsp;</p><p>&nbsp;</p>

请将此更新为

<p class="find">&nbsp;</p><p>&nbsp;</p>

你会看到代码中断。这就是我的意思,当我搜索一个词(在JSFIDDLE的情况下,单词'find'),然后我只想通过网站副本搜索。

如您所知,您必须处理整个(或部分)DOM。在执行此操作时,您必须根据不想处理的标签黑名单对每个tagName进行交叉检查。

下面是一个小示例,说明如何在普通javascript中完成此操作:

var excludeElements = ['script', 'style', 'a', 'form', 'iframe', 'canvas'];
var markText = function(textToHighlight) {
    walk(document.body, textToHighlight, function(node, match, offset) {
        var abbrevNode = document.createElement("span");
        abbrevNode.appendChild(document.createTextNode(textToHighlight));
        abbrevNode.className="someClass";
    });
}
var walk = function(node, textToHighlight, callback) { 

    var child = node.firstChild;
    while (child) {
        switch (child.nodeType) {
        case 1:
            if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1)
                break;
            walk(child, textToHighlight, callback);
            break;
        case 3:
            var bk = 0;
            child.data.replace(textToHighlight, 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;
            });
            break;
        }
        child = child.nextSibling;
    }
    return node;
};