1

我在客户端使用 C# 和 javascript 编写自己的自动完成文本框控件。在客户端,我想替换字符串中与用户正在搜索的字符匹配的字符以突出显示它。例如,如果用户正在搜索字符“bue”,我想替换单词“marbuel”中的这些字母,如下所示:

mar<span style="color:#81BEF7;font-weight:bold">bue</span>l

为了给匹配的部分另一种颜色。如果我的自动完成中有 100-200 个项目,这工作得很好,但是当涉及到 500 个或更多时,它会花费太多时间。

以下代码显示了我的方法,它为此执行了逻辑:

 HighlightTextPart: function (text, part) {
    var currentPartIndex = 0;
    var partLength = part.length;
    var finalString = '';
    var highlightPart = '';
    var bFoundPart = false;
    var bFoundPartHandled = false;
    var charToAdd;
    for (var i = 0; i < text.length; i++) {
        var myChar = text[i];
        charToAdd = null;
        if (!bFoundPart) {
            var myCharLower = myChar.toLowerCase();
            var charToCompare = part[currentPartIndex].toLowerCase();
            if (charToCompare == myCharLower) {
                highlightPart += myChar;
                if (currentPartIndex == partLength - 1)
                    bFoundPart = true;

                currentPartIndex++;
            }
            else {
                currentPartIndex = 0;
                highlightPart = '';
                charToAdd = myChar;
            }
        }
        else
            charToAdd = myChar;

        if (bFoundPart && !bFoundPartHandled) {
            finalString += '<span style="color:#81BEF7;font-weight:bold">' + highlightPart + '</span>';
            bFoundPartHandled = true;
        }

        if (charToAdd != null)
            finalString += charToAdd;
    }
    return finalString;
},

这种方法只突出匹配部分的第一次出现。我使用它如下。一旦请求从服务器返回,我通过遍历每个项目来构建一个包含匹配项目的 html UL 列表,并且在每个循环中我调用此方法以突出显示匹配的部分。

正如我对多达 100 件物品所说的那样,它炒起来非常好,但对于 500 件或更多来说它太笨拙了。

有没有办法让它更快?也许通过使用正则表达式或其他一些技术?

我还考虑过使用“setTimeOut”在一个额外的函数中执行此操作,或者仅对当前可见的项目执行此操作,因为只有几个项目是可见的,而其他项目则必须滚动。

4

3 回答 3

0

JavaScript 中的字符串替换非常简单String.replace()

function linkify(s, part)
{
    return s.replace(part, function(m) {
        return '<span style="color:#81BEF7;font-weight:bold">' + htmlspecialchars(m) + '</span>';
    });
}

function htmlspecialchars(txt)
{
    return txt.replace('<', '&lt;')
        .replace('>', '&gt;')
        .replace('"', '&quot;')
        .replace('&', '&amp;');
}

console.log(linkify('marbuel', 'bue'));
于 2013-05-04T16:51:45.903 回答
0

尝试限制可见列表大小,例如,您最多只能显示 100 个项目。从可用性的角度来看,甚至可能只有 20 个项目,所以它会比这更快。还可以考虑使用类 - 看看它是否能提高性能。所以而不是

mar<span style="color:#81BEF7;font-weight:bold">bue</span>l

你会有这个:

mar<span class="highlight">bue</span>l
于 2013-05-04T16:44:59.597 回答
0

我通过使用正则表达式而不是我之前发布的方法解决了这个问题。我现在用以下代码替换字符串:

return text.replace(new RegExp('(' + part + ')', 'gi'), "<span>$1</span>");

这是相当快的。比上面的代码快得多。自动完成中的 500 项似乎没有问题。但是任何人都可以解释一下,为什么这比我的方法更快,或者使用 string.replace 而不使用正则表达式?我不知道。

谢谢!

于 2013-05-07T22:51:50.113 回答