0

私が構築してきたオートコンプリート機能を備えた検索ボックスがあります。いくつか問題があります。

2つのこと:

  • オートコンプリート/検索用語のリストを上下に矢印で移動すると、フィルターによって非表示になったものも含まれます。表示されているリスト項目のみをトラバースできるようにするにはどうすればよいですか?

  • Enter キーを押してリストから項目の 1 つを選択すると、検索ボックス内の単語と一致するため、ドロップダウンがまだ表示されます。

フィドル

いくつかのコード:

$(document).ready(function() {
    $("#dropdown").hide();
    $("input").keyup(function() {
        if (this.value.length) {
            var that = this;
            $("#dropdown li").hide().filter(function() {
                return $(this).html().toLowerCase().indexOf(that.value.toLowerCase()) !== -1;
            }).show();
            $("#dropdown").show();
        }
        else {
            $("#dropdown").hide();
        }
    });

    $('li').click(function() {
        $('#search').val($(this).text());
        $("#dropdown").hide();
    });

    var li = $('li');
    var liSelected;

    $('input').keydown(function(e) {
        if(e.which === 40) {
            if(liSelected) {
                liSelected.removeClass('selected');
                next = liSelected.next();
                if(next.length > 0) {
                    liSelected = next.addClass('selected');
                    $('#search').val(liSelected.text());
                }
                else {
                    liSelected = li.eq(0).addClass('selected');
                }
            }
            else {
                liSelected = li.eq(0).addClass('selected');
            }
        }
        else if(e.which === 38) {
            if(liSelected) {
                liSelected.removeClass('selected');
                next = liSelected.prev();

                if(next.length > 0) {
                    liSelected = next.addClass('selected');
                }
                else {
                    liSelected = li.last().addClass('selected');
                }
            }
            else {
                liSelected = li.last().addClass('selected');
            }
        }
        else if(e.which === 13) {
            $('#search').val(liSelected.text());
            $("#dropdown").hide()
            $('#search').blur();
        }
    });
});
4

1 に答える 1

1

ポイントは、.filter() 呼び出しからの要素のみを表示していることですが、要素は同じリストにまだ存在しています。非表示の要素を配置する別のリスト、hidden を作成する必要があります。ユーザーが検索フィールドを更新するたびに、両方のリストの各要素をチェックする必要があります。表示する必要があるものは表示リストに入れ、表示したくないものは隠しリストに入れます。

これが例です

$("input").keyup(function(e) {
    if (this.value.length) {
        var that = this;
        $("#dropdown li").each(function() {

            if ( $(this).html().toLowerCase().indexOf(that.value.toLowerCase()) == -1 )
                $(this).appendTo($hidden);
        });
        $('#hidden li').each(function() {
            if ( $(this).html().toLowerCase().indexOf(that.value.toLowerCase()) !== -1 )
                $(this).appendTo('#list');
        });
        $("#dropdown").show();
    }
    else {
        $("#dropdown").hide();
    }
    if ( e.which !== 40 && e.which !== 38 )
    {
        $('#dropdown li,#hidden li').each( function() {
            $(this).removeClass( 'selected' );
        });
        liSelected = null;
    }                                            
});

毎回チェックするリストが 2 つになりました。li の数と位置は常に変化しているため、以前のように li の結果をキャッシュすることはできません。

ここで、コードを変更して、私の意味を示します。バグがあるかもしれませんが、要点を理解する必要があります。

于 2012-10-26T14:41:13.823 に答える