3

我已经为一个页面编写了一个简单的 javascript 搜索器,并且遇到了一些不匹配/错误匹配以及可能较差的 css 类匹配的问题。

http://jsfiddle.net/C4q7T/

如果我单击第一个示例“代码”(过滤到一个元素),然后在“样式”链接上,“代码”突出显示仍然存在。不用说这是不可取的。

我认为问题将发生在代码的过滤部分,但对我来说一切都很好。特别是因为我正在抓取标题的文本而不是它的 HTML,然后添加一个新的跨度。

function filter(searchTerm) {
    var searchPattern = new RegExp('(' + searchTerm + ')', 'ig');  // The brackets add a capture group

    entries.fadeOut(150, function () {
        noResults.hide();

        $('header', this).each(function () {
            $(this).parent().hide();

            // Clear results of previous search
            $('li', this).removeClass('searchMatchTag');

            // Check the title
            $('h1', this).each(function () {
                var textToCheck = $('a', this).text();
                if (textToCheck.match(searchPattern)) {
                    textToCheck = textToCheck.replace(searchPattern, '<span class="searchMatchTitle">$1</span>');  //capture group ($1) used so that the replacement matches the case and you don't get weird capitolisations
                    $('a', this).html(textToCheck);
                    $(this).closest('.workshopentry').show();
                }
            });

            // Check the tags
            $('li', this).each(function () {
                if ($(this).text().match(searchPattern)) {
                    $(this).addClass('searchMatchTag');
                    $(this).closest('.workshopentry').show();
                }
            });
        });

        if ($('.workshopentry[style*="block"]').length === 0) {
            noResults.show();
        }

        entries.fadeIn(150);
    });
}

其他一些组合会发生这种情况,但其他一些组合不会,这让我很难找到这个特定问题的原因。

4

3 回答 3

4

如果没有正确引用,您将无法使用正则表达式信任用户输入。考虑使用这样的引用函数:

var rePattern = searchTerm.replace(/[.?*+^$\[\]\\(){}|]/g, "\\$&"),
searchPattern = new RegExp('(' + rePattern + ')', 'ig');  // The brackets add a capture group

编辑

如评论中所述,尚不清楚为什么要使用捕获括号来执行搜索;您可以$&用作替换模式。当然,如果您简化了这篇文章的正则表达式,我会理解 :)

于 2012-11-21T06:53:03.647 回答
1

在不转义 searchTerm 的情况下生成 searchPattern 可能是个问题。的 searchTerm.*将匹配任何内容。

改用怎么样var match = textToCheck.indexOf(searchTerm) >= 0

这将返回文本中子字符串的第一个实例的索引searchTerm,否则,它将返回 -1。

于 2012-11-21T06:40:29.883 回答
0

原来我错过了删除以前匹配标签的检查。

var textToCheck = $('a', this).text();
if (textToCheck.match(searchPattern)) {
    //capture group ($1) used so that the replacement matches the case and you don't get weird capitolisations
    textToCheck = textToCheck.replace(searchPattern, '<span class="searchMatchTitle">$1</span>');
    $('a', this).html(textToCheck);
    $(this).closest('.workshopentry').show();
} else {
    $('a', this).html(textToCheck);
}
于 2012-12-05T12:47:44.670 回答