【问题标题】:Highlighting text in document (JavaScript) Efficiently有效地突出显示文档中的文本 (JavaScript)
【发布时间】:2012-05-23 23:57:02
【问题描述】:

我如何(有效地 - 不降低计算机 [cpu] 速度)突出显示页面的特定部分?

假设我的页面是这样的:

<html>
<head>
</head>
<body>
"My generic words would be selected here" !.
<script>
//highlight code here
var textToHighlight = 'selected here" !';
//what sould I write here?
</script>
</body>
</html>

我的想法是将所有正文“克隆”到一个变量中,并通过 indexOf 找到指定文本,更改(插入带有背景色的跨度)“克隆”字符串并将“真实”正文替换为“克隆”一个。
我只是认为它没有效率。
你还有其他建议吗? (有创意:))

【问题讨论】:

    标签: javascript performance highlight


    【解决方案1】:

    我根据我对 SO (example) 上几个类似问题的回答改编了以下内容。它被设计为可重复使用的,并且已被证明是可重复使用的。它遍历您指定的容器节点内的 DOM,在每个文本节点中搜索指定文本,并使用 DOM 方法拆分文本节点并将相关文本块包围在样式 &lt;span&gt; 元素中。

    演示:http://jsfiddle.net/HqjZa/

    代码:

    // Reusable generic function
    function surroundInElement(el, regex, surrounderCreateFunc) {
        // script and style elements are left alone
        if (!/^(script|style)$/.test(el.tagName)) {
            var child = el.lastChild;
            while (child) {
                if (child.nodeType == 1) {
                    surroundInElement(child, regex, surrounderCreateFunc);
                } else if (child.nodeType == 3) {
                    surroundMatchingText(child, regex, surrounderCreateFunc);
                }
                child = child.previousSibling;
            }
        }
    }
    
    // Reusable generic function
    function surroundMatchingText(textNode, regex, surrounderCreateFunc) {
        var parent = textNode.parentNode;
        var result, surroundingNode, matchedTextNode, matchLength, matchedText;
        while ( textNode && (result = regex.exec(textNode.data)) ) {
            matchedTextNode = textNode.splitText(result.index);
            matchedText = result[0];
            matchLength = matchedText.length;
            textNode = (matchedTextNode.length > matchLength) ?
                matchedTextNode.splitText(matchLength) : null;
            surroundingNode = surrounderCreateFunc(matchedTextNode.cloneNode(true));
            parent.insertBefore(surroundingNode, matchedTextNode);
            parent.removeChild(matchedTextNode);
        }
    }
    
    // This function does the surrounding for every matched piece of text
    // and can be customized  to do what you like
    function createSpan(matchedTextNode) {
        var el = document.createElement("span");
        el.style.backgroundColor = "yellow";
        el.appendChild(matchedTextNode);
        return el;
    }
    
    // The main function
    function wrapText(container, text) {
        surroundInElement(container, new RegExp(text, "g"), createSpan);
    }
    
    wrapText(document.body, "selected here");
    

    【讨论】:

    • 我的问题是我不知道父节点。所以在这方面它不会那么有效。
    • @agam360:你不需要知道父节点,只需要一个祖先节点。 innerHTML 解决方案也需要它,我的解决方案通常会优于基于 innerHTML 的解决方案,并且更健壮(例如,考虑包含搜索词的属性)。
    • 在再次包装之前如何清理被包装的东西?见demo
    【解决方案2】:
    <html>
    <head>
    </head>
    <body>
    <p id="myText">"My generic words would be selected here" !.</p>
    <script>
    //highlight code here
    var textToHighlight = 'selected here" !';
    var text = document.getElementById("myText").innerHTML
    document.getElementById("myText").innerHTML = text.replace(textToHighlight, '<span style="color:red">'+textToHighlight+'</span>');
    //what sould I write here?
    </script>
    </body>
    </html>
    

    【讨论】:

    • 您的效率问题是什么? 高效 本身并不能提供足够的信息。
    • @SelimOber,我的意思是高效:- 低 CPU 消耗
    • 您的操作有两种方法: 1 - 使用正则表达式 => 需要很多资源(CPU 密集型) 2 - 查找字符串并在没有 Regex 的情况下替换(参见我的示例) => perfomant 但是不限于复杂的字符串对不起我的英语
    • 更大的问题是替换潜在复杂元素的整个innerHTML 效率低下,这将使使用正则表达式的任何低效率相形见绌。另一种方法是 DOM 遍历。
    【解决方案3】:

    thisthis 结合使用,应该没问题。 (这几乎比尝试自己实现选择/选择高亮逻辑要好。)

    【讨论】:

      猜你喜欢
      • 2018-08-29
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      • 2013-09-15
      • 2011-02-21
      相关资源
      最近更新 更多