在输入框内实时搜索

3

我需要你的帮助。

我如何在现有代码中添加一些功能,以便我能够使用输入框在ul列表中搜索,并自动突出显示每个匹配项,就像(查找-当您键入)样式的搜索一样?

我喜欢使用jQuery :)

对于那些想要测试的人,这里是一个fiddle:http://jsfiddle.net/83sPQ/1/

以下是标记:

<!DOCTYPE html>

<html>

<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 

<style type="text/css">
* {
    font-family: Segoe UI;
    font-size: 9pt;
}
#refdocs {
    border: 0;
    width: 100%;
    height: auto;
    padding-left: 2px;
}
#refdocs_main {
    border: 1px solid rgb(170,170,170);
    width: 179px;
    overflow: hidden;
    margin-top: 1px;
}
#refdocs_input{
    border-bottom: 1px solid rgb(170,170,170);
    height: 20px;

}
#refdocs_wrapper{
    height: 100px;
    overflow-y: scroll;
    overflow-x: hidden;
}
#refdocs_list {
    width: 100%;
}
#refdocs_list ul {
    margin: 0;
    padding: 0px;
    list-style-type: none;
}
#refdocs_list li {
    cursor: default;
    padding: 2px;
}
.selected {
    background: rgb(228,228,228);
}

</style>

<script type="text/javascript">
window.onload = function() {
    $('#refdocs_list ul li').click(function () {
        $('#refdocs_list ul li').removeClass('selected');
        $(this).addClass('selected');
        document.getElementById('refdocs').value = $(this).text()
    });


}




</script>

</head>

<body>

    <div id="refdocs_main">

        <div id="refdocs_input"><input type="text" id="refdocs"></div>

        <div id="refdocs_wrapper">

            <div id="refdocs_list">
                <ul>
                    <li>9094203</li>
                    <li>9279863</li>
                    <li>9023698</li>
                    <li>8993127</li>
                    <li>9037891</li>
                    <li>(red)</li>
                    <li>tiger</li>
                    <li>The lion</li>
                    <li>Ted</li>
                </ul>
            </div>

        </div>

    </div>

</body>

</html>

1
你的代码中实际上在哪里监听输入的 keydown 事件?你尝试过什么来完成你的任务? - undefined
...还有多少个字母/字符应该匹配? - undefined
1
$('#refdocs').on('keyup', function() { var val = $(this).val(); $('#refdocs_list li').each(function() { $(this).toggle(!!$(this).text().match(val)); }); }); - undefined
@acbabis 你想切换什么? - undefined
@RokoC.Buljan 对于每个li,检查它是否匹配该值,将结果转换为布尔值,并将其传递给toggle函数。 - undefined
显示剩余7条评论
2个回答

4
$('#refdocs').on('keyup change', function () {
    var search = $(this).val();
    $('#refdocs_list li').each(function () {
        var val = $(this).text();
        $(this).toggle( !! val.match(search)).html(
            val.replace(search, function(match) {
                    return '<mark>'+match+'</mark>'}, 'gi')
        );
    });
});

每当用户输入时,li元素会根据是否与正则表达式匹配动态隐藏或显示。同时,使用搜索文本作为正则表达式将匹配项用mark标签包裹以突出显示其文本。

http://jsfiddle.net/acbabis/4cfQ8/

编辑:根据要求,这里提供一个更加健壮的解决方案:

$('#refdocs').on('keyup change', function () {
    var search = $(this).val();
    var searchLen = search.length;
    // Case-insensitive search with regex characters escaped
    // For case-sensitive, no regex is needed. Use indexOf() instead of search().
    // Attr: https://dev59.com/AXA65IYBdhLWcg3w7DT8#3561711
    var regex = new RegExp(
            search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'i');
    $('#refdocs_list li').each(function () {
        var li = $(this);
        var val = li.text();
        if (searchLen === 0) {
            li.show().text(val); // Remove inner markup
            return;
        }
        var index;
        var isMatch = false;
        li.html('');
        while ((index = val.search(regex)) != -1) {
            isMatch = true;
            if (index !== 0) {
                var nonMatch = val.substring(0, index);
                li.append($('<span>').text(nonMatch));
            }
            var match = val.substring(index, index + searchLen);
            val = val.substring(index + searchLen);
            li.append($('<mark>').text(match));
        }
        if (val.length) {
            li.append($('<span>').text(val));
        }
        li.toggle(isMatch); // Optional. Hide non-matches
    });
});

这段代码依赖于jQuery的text()函数对HTML转义字符的处理能力。

http://jsfiddle.net/acbabis/3bUxe/


我真的很喜欢你的解决方案,希望也许你能让它适用于用户输入特殊字符,比如括号、感叹号、井号等。有没有一种简洁的方法可以修改你的脚本来包含特殊字符? - undefined
这对我很有帮助,谢谢!不过我有个问题,在你的第一个回答中,为什么在替换文本中使用了一个函数?我尝试只使用'<mark>'+match+'</mark>'也可以工作。另外,为什么在.replace方法中有3个参数?gi是什么意思?是全局不区分大小写的代码吗? - undefined
没有函数,变量match就不存在。不过你可以使用'<mark>$1</mark>'。我不确定为什么你的会起作用。 - undefined

2

这应该是一个合理的解决方案:

$('#refdocs').keyup(function (event) {
    var text = $(this).val();
    $('#refdocs_list ul li').each(function () {
        var elem = $(this);
        elem.removeClass('selected');
        if (elem.html().indexOf(text) != -1) {
            elem.addClass('selected');
        }
    });
});

JSFiddle: http://jsfiddle.net/83sPQ/4/


好的解决方案。你甚至可以使用 if (elem.html().toLowerCase().indexOf(text.toLowerCase()) != -1) { 来实现不区分大小写。 - undefined
@agrm,感谢你的评论伙计。如果需要的话,我相信作者也会加入你的改进。 - undefined
不错的解决方案,你可以添加一个类.hided:{display:none;},并在你的if语句中选择匹配和隐藏非匹配元素,并使用else - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接