1

我有一个 jQuery 自动完成功能,用户的搜索词在搜索结果中突出显示。多亏了stackoverflow,我已经完成了大部分工作,并且突出显示了这些术语。

当第二个术语在使第一个突出显示的代码中匹配时出现问题,因此部分 HTML 被突出显示。例如,如果搜索词是“word1 te”并且返回的结果包含:

“这是 word1,我正在测试”

在我的循环的第一次迭代中,它会变成:“这是<span class='highlightedText'>word1 </span>,我正在测试”

其次,它不仅会突出“testing”中的“te”,还会突出“highlightedText”中的“te”。例如“这是测试<span class='highlight<span class='highlightedText'>stingText </span>'>word1 </span>,我正在<span class='highlightedText'>测试</span>

<span class='highlightedText'>$1</span>现在,我可以通过将高亮文本设置为粗体来简化高亮文本,这样就可以代替,<b>$1</b>但是如果我的用户自己输入字母“b”,该标签将被标记。

我可以尝试以某种方式排除突出显示的字母“b”,但我希望有人有一个更优雅的解决方案。

呸!希望这很清楚。

这是我到目前为止所得到的:

CSS:

.highlightedText {
    color: blue; font-weight:bold;
}

在stackoverflow上找到的正则表达式:

    /**
    * http://kevin.vanzonneveld.net
    *   original by: booeyOH
    *   improved by: Ates Goral (http://magnetiq.com)
    *   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    *   bugfixed by: Onno Marsman
    *     example 1: preg_quote("$40");
    *     returns 1: '\$40'
    *     example 2: preg_quote("*RRRING* Hello?");
    *     returns 2: '\*RRRING\* Hello\?'
    *     example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
    *     returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:' 
 */
function preg_quote( str ) {
    return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
}

这是我的代码:

$("#search_member").autocomplete({
          minLength: 2,
          source: '/controller/module/action/term/' + $(this).val(),
          delay: '500',
          select: function (event, ui) {
                  // delete what they input
                  $(this).val('');
                  // the 'value' is a URL to navigate to
                  window.location.href = '/controller/module/index/mem_code/' + ui.item.mem_code;
                  // don't populate the autocomplete box
                  return false;
          }
    }).data("autocomplete")._renderItem = function (ul, item) {
        // search and replace matched search terms with bold version
        var highlighted = item.fullname;
        var termsString = this.term;
        var termsArr = termsString.split(' ');
        for (var i = 0; i < termsArr.length; i++) {
            var term = termsArr[i];
            highlighted = (highlighted+'')
                            .replace( 
                                new RegExp( "(" + preg_quote( term ) + ")" , 'gi' )
                                , "<span class='highlightedText'>$1</span>" 
            );
        }

        var listItem = '<a>' + highlighted + ' ' + 
                    item.type_code + '</a>' ;

        $("<li></li>").data("item.autocomplete", item)
                      .append(listItem)
                      .appendTo(ul);
        return;
    };

    // clear the search box if clicked
    $('.span_link').click(function() {
        $('#search_member').val('');
        $('#table_container').hide();
    });    
4

1 回答 1

1

实际上在我提交之前找到了答案,但尽管我还是会提交它,以防它帮助其他人。

问题是我的 for 循环;不需要它,只需改进我的 reg-ex 以便它一次性替换所有单词。这是更正后的“_renderItem”函数:

.data("autocomplete")._renderItem = function (ul, item) {
    // search and replace matched search terms with bold version
    var highlighted = item.fullname;
    var termsString = this.term.trim();
    var words = termsString.split(' ').join('|');
    var regExp = new RegExp( "(" +  words + ")" , 'gi' );

     highlighted = (highlighted+'')
                     .replace( 
                         regExp
                         , "<span class='ui-state-highlight'>$1</span>" 
     );

    var listItem = '<a>' + highlighted + ' ' + 
                item.type_code + '</a>' ;

    $("<li></li>").data("item.autocomplete", item)
                  .append(listItem)
                  .appendTo(ul);
    return;
};

不需要 preg_quote() 函数或自定义 CSS 片段。

于 2013-02-18T10:20:01.040 回答