0

値のリスト(少数)で理想的に検索を実行するコードの1つに検索機能があります。

<li>abc</li> 
<li>def</li> 
...

下部に検索ボタンがあり、keyupイベントリスナーを配置してインスタント検索を取得します。ここで問題となるのは、どうすればナビゲート可能にすることができるかということです。理想的なシナリオでは、テキストを検索し、Enterキーを押すと、最初の要素が開きます。それ以外の場合は、ナビゲートできるはずです。

上記が明確でない場合は、Facebookチャットのサイドバー検索に非常によく似た機能を実際に求めています。

4

4 に答える 4

1

タグのリストにjQueryを追加していないOPのために(おめでとうございます)、純粋なJavaScriptで小さなナビゲーションプラグインを追加します。

開示-実際のロジックの功績は、Facebookで有名なEric Priestleyに与えられます。これは、彼のJavelinJSライブラリから削除されたためです。

ここにフィドルへのリンクを投稿しています。また、あなたの質問から、あなたはすでに検索ソリューションを導入していて、単にナビゲーションソリューションを探していると思います。

フィドルからのクロスポスト。私はコードでたくさんコメントしたので、自明であるはずです。疑問がある場合は、連絡してください。

HTML はあなたが望むものなら何でもかまいません。簡潔にするために、これを追加しました

<input id='control' type='text' placeholder='Search text here' />
<!-- List of results - hardcoded for now -->
<ul id='hardpoint' class='hidden'>
    <li class='item'>Search item 1</li>
    <li class='item'>Search item 2</li>
    <li class='item'>Search item 3</li>
    <li class='item'>Search item 4</li>
</ul>​

コード

(function() {


    /**
     * Helper functions
     */
    var bind = function( context, func, more ){
        if (typeof func !== 'function') {
            throw new Error ("No function supplied to bind function");
        }
        var bound = Array.prototype.slice.call( arguments ).slice(2);
        if (func.bind) {
            return func.bind.apply(func, [context].concat(bound));
        }
        return function() {
            return func.apply(context || window, bound.concat(Array.prototype.slice.call( arguments )));
        }
    };

    var getChildElements = function(node) {
        var childNodes = Array.prototype.slice.call(node.childNodes);
        childNodes = childNodes.filter(function(item) {
            return item.tagName && item.nodeType && item.nodeType === 1 && item !== node;
        });
        return childNodes;
    };

    var hasClass = function(node, className) {
        return ((' ' + node.className + ' ').indexOf(' ' + className + ' ') > -1);
    };

    var alterClass = function(node, className, add) {
        var has = hasClass(node, className);
        if (add && !has) {
            node.className = node.className.trim() + ' ' + className;
        }
        else if (has && !add) {
            node.className = node.className.replace(
            new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), ' ');
        }
    };

    var getIndex = function( list, element ){
        var index = -1;
        for (var i = 0; i < list.length; i++) {
            if( list[i] === element ){
                index = i;
                break;
            }
        };
        return index;
    };


    // Start of plugin
    // Constructor
    var ListNavigator = function(config) {};

    // This can be moved within constructor if you so prefer
    ListNavigator.prototype.init = function(config) {
        // On what element do you want the controls to activate
        // Pressing up down etc on this element, triggers tha navigation
        this.control = document.getElementById(config.control);

        // The list of results that can be navigated
        this.hardpoint = document.getElementById(config.hardpoint);

        // A list of items ( usually, childNodes ) of hardpoint
        // Dynamically populated
        this.display =  getChildElements(this.hardpoint);;

        // What to set the focus on initially
        this.focus = -1;

        // Specify a function to execute when the user chooses a result
        // Keydown - Return : configured to be the choose event type now
        this.choose = config.choose;

        this.selector = config.selector;
    };

    ListNavigator.prototype.run = function() {
        var controlEvents = ['focus', 'blur', 'keydown', 'input'],
            mouseEvents = [ 'mouseover', 'mouseout', 'mousedown' ],
            self = this,
            selector = this.selector;

        controlEvents.forEach(function(event) {
            self.control.addEventListener(event, bind(self, self.handleEvent), false);
        });

        mouseEvents.forEach(function(event) {
            self.hardpoint.addEventListener(event, bind(self, self.onmouse), true);
        });
    };

    // Logic to change the focus on keydown
    ListNavigator.prototype.changeFocus = function(d) {
        var n = Math.min( Math.max( -1, this.focus + d ), this.display.length - 1);

        if (this.focus >= 0 && this.focus < this.display.length) {
            alterClass(this.display[this.focus], 'focused', false);
        }

        this.focus = n;
        this.drawFocus();
        return true;
    };

    // Set the focus on the targetted element
    ListNavigator.prototype.drawFocus = function() {
        var f = this.display[this.focus];
        if (f) {
            alterClass(f, 'focused', true);
        }
    };

    // Handle mouse events
    ListNavigator.prototype.onmouse = function(event) {
        var target = event.target, type = event.type;
        if ( hasClass( target, this.selector ) ) {
            if ( type === 'mousedown' ) {
                // Choose this element
                this.choose(target);
            }
            else if ( type === 'mouseover' ) {
                // Set the focus to element on which mouse is hovering on
                this.focus = getIndex( this.display, target );
                this.drawFocus();
            } 
            else if ( type === 'mouseout' ){
                // Reset the display to none
                this.changeFocus(Number.NEGATIVE_INFINITY);
            }
        };
    };

    ListNavigator.prototype.handleEvent = function(e) {
        var type = e.type;
        if (type === 'blur') {
            this.focused = false;
            this.hide();
        } else {
            alterClass(this.hardpoint, 'hidden', false);
            this.update(e);
        }
    };

    ListNavigator.prototype.hide = function() {
        this.changeFocus(Number.NEGATIVE_INFINITY);
        this.display = [];
        alterClass(this.hardpoint, 'hidden', true);
    };

    ListNavigator.prototype.submit = function() {
        if (this.focus >= 0 && this.display[this.focus]) {
            this.choose(this.display[this.focus]);
        } else {

            if (this.display.length) {
                this.changeFocus(1);
                this.choose(this.display[this.focus]);
            }
        }
        return false;
    };

    ListNavigator.prototype.update = function(event) {

        console.log( 'upadte' );
        this.display = getChildElements(this.hardpoint);

        if (event.type === 'focus') {
            this.focused = true;
        }

        var k = event.which;
        if (k && event.type == 'keydown') {
            switch (k) {
            case 38:
                if (this.display.length && this.changeFocus(-1)) {
                    event.stopPropagation();
                }
                break;
            case 40:
                if (this.display.length && this.changeFocus(1)) {
                    event.stopPropagation();
                }
                break;
            case 13:
                if (this.display.length) {
                    this.hide();
                    event.stopPropagation();
                    this.submit();
                }
                break;
            case 27:
                if (this.display.length) {
                    this.hide();
                    event.stopPropagation();
                }
                break;
            case 9:
                // If the user tabs out of the field, don't refresh.
                return;
            }
        }

    };

    window.ListNav = ListNavigator

})();

var nav = new ListNav();
nav.init({
    control: 'control',
    hardpoint: 'hardpoint',
    selector: 'item',
    choose: function(){
        console.log( arguments );
    }
});
nav.run();​
于 2012-11-15T17:19:21.303 に答える
0

これが私のページの場合、などのクラスでタグ付けされた検索可能な要素があり、 jQueryを使用して、以前にvar SEARCHTERM = $( "#searchbox")を定義した場所<li class="searchable">abc</li>などのセレクターを介してページ内のすべての検索可能な要素を検索します。$("li.searchable:contains('" + SEARCHTERM + "')")文章();

これを使用して行うことができる微調整がいくつかあります(たとえば、:containsは大文字と小文字を区別します)が、これは正しい方向にあるように聞こえますか?

于 2012-11-14T02:46:07.130 に答える
0

オートコンプリート機能をお探しですか...?その場合は、jQuery UIオートコンプリートを調べる必要があります:http://jqueryui.com/autocomplete/

于 2012-11-14T13:09:39.937 に答える
0
<html lang="html">
<head>
<meta charset="utf-8" />
<title>Search Users</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
    $("#searched_users_list").hide();
    $("#search_user").keyup(function(){
        var what_to_search = $(this).val().toLowerCase();
        if(what_to_search != ''){
            $("#users_list").hide();
            $("#searched_users_list").show();
        }else{
            $("#users_list").show();
            $("#searched_users_list").hide();
        }
        var searched_users = '';
        var user_name = '';
        $("#users_list").children('li:contains("'+what_to_search+'")').each(function(){
            user_name = $(this).html();
            searched_users += "<li>"+user_name+"</li>";
        });

        if(searched_users != '')
            $("#searched_users_list").html(searched_users);
        else
            $("#searched_users_list").html('<li>No user found....</li>');
    })
});
</script>
</head>
<body>
<ul id="users_list">
    <li>abc</li>
    <li>defa</li>
    <li>ghife</li>
</ul>
<ul id="searched_users_list">
    <li>No user found....</li>
</ul>
<input type="text" name="search_users" id="search_user" value="" />
</body>
</html>

It's my first post... Sorry If something is odd.
于 2012-11-15T10:53:06.377 に答える