dougan4663
dougan4663
采纳率0%
2016-07-21 05:10

自动建议下拉菜单未使用向上/向下箭头键选择

I have a pretty basic auto-suggestion function for my website which operates whenever a user enters something into my search input.

It is supposed to function kind of like Googles search auto-suggestion - and it sort of does. However, when some suggestions are returned, if the user hits one of the arrows on their keyboard, it will not select any suggestion.

Here is my JS (for the selection of a suggestion):

$(document).ready(function(){
    var $result = $('li');

    $('input').keydown(function(e){
        var key = e.keyCode, $selected = $result.filter('.selected'), $current;
        if(key != 40 && key != 38){ 
            return;
        }
        $result.removeClass('selected');
        if (key == 40){
            if (!$selected.length || $selected.is(':last-child')){
                $current = $result.eq(0);
            } else {
                $current = $selected.next();
            }
        } else if (key == 38){
            if (!$selected.length || $selected.is(':first-child')){
                $current = $result.last();
            } else {
                $current = $selected.prev();
            }
        }

        $current.addClass('selected');
    });
});

Here is my Ajax:

function findmatch(){
    if(window.XMLHttpRequest){
        xmlhttp = new XMLHttpRequest();
    } else {
        xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
    }

    xmlhttp.onreadystatechange = function(){
        if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
            document.getElementById('s-dif').innerHTML = xmlhttp.responseText;
        }
    }

    var qVal = document.getElementById('query-value');

    xmlhttp.open('GET', 'search/suggest.php?q=' + qVal.value, true);
    xmlhttp.send();
}

The very basic HTML:

<div class="form-container">
    <form method="get" id="search" name="search">
        <input type="text" name="q" id="query-value" onkeyup="findmatch();" placeholder="Search with Ajax...">
    </form>
</div>
<div class="suggestions">
    <ul id="s-dif">
    </ul>
</div>

and finally, my PHP:

if(isset($_GET['q'])){
    $results = '';

    $query = trim($_GET['q']);  
    if(!empty($query)){
        $stmt = $conn->prepare("SELECT title, popularity FROM autosuggest WHERE keywords LIKE :query OR title LIKE :query ORDER BY popularity desc LIMIT 7");
        $query = $query . '%';
        $stmt->bindParam(':query', $query);
        $stmt->execute();

        $count = $stmt->rowCount();
        $i = 0;
        if($count > 0){
            while($row = $stmt->fetch(PDO::FETCH_OBJ)){
                $title = $row->title;
                $popularity = $row->popularity;

                $i++;

                $results .= '<li id="select-suggest" value="' . $i . '" name="' . $title . '">' . $title . '</li>';
            }   
        }
    }
}

print("$results");

I feel as if the problem lies within my "selection jQuery", however, I have made sure to triple check everything, but I cannot seem to find anything that would stop the feature from working.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • duanjiwei1283 duanjiwei1283 5年前

    I am not sure how Google works, but I believe you are try to do something like the below script. You should be able to apply it to your returned dropdown menu. It checks that the cursor is focused in the input field. If it is, then activate the keyCode script below:

    jsFiddle: https://jsfiddle.net/2wvs0tmd/

    JavaScript:

    // I am going to use an object, just for reuse
    /*
    ** @param jQuery [object] Pass the jQuery object
    ** @param getMenu [object] jQuery DOM object (ul) that contains our menu
    ** @parm getKeyTap [int] This is the e.keyCode passed from the event
    */
    var keyAction   =   function(jQuery,getMenu,getKeyTap)
        {
            // The variable is what is currently be acted on
            var isSelected;
            // This will designate first or last child
            var getChild;
            // This will be assigned the next, previous, or current child
            var thisChild;
            // We assign jQuery here
            var $           =   jQuery;
            // These are all the keys we allow to be struck
            var allowKeys   =   [38,40,13];
            // This is not used in this example, but can reset the keyCode
            var keyCode     =   false;
            /*
            ** @returns [boolean] This function returns if the key being pressed is arrow up/down
            */
            var upDown      =   function(getKeyTap)
                {
                    return (getKeyTap == 38 || getKeyTap == 40);
                }
            /*
            ** @returns [boolean] This method returns boolean true/false if up/down arrow pressed
            */
            this.keyAllowed =   function()
                {
                    return upDown(getKeyTap);
                }
            /*
            ** @description This method sees if pressed key is up/down arrow or return key
            ** @returns [boolean] Will return true/false
            */
            this.isAllowed  =   function()
                {
                    return (allowKeys.indexOf(getKeyTap) != -1);
                }
            // This will manually set the keyCode (not required in this example)
            this.setKey =   function(keyCode)
                {
                    getKeyTap   =   keyCode;
                    return this;
                }
            /*
            ** @returns [object] This returns the current state of the DOM 
            */
            this.isSelected =   function()
                {
                    return isSelected;
                }
            /*
            ** @description This will run an anonymous function passing the current DOM
            ** @param thisChild [ANY] I pass the current DOM selection but, you 
            **                        can pass whatever you want 
            ** @param func [function] This is what you want to run when the 
            **                        return key is pressed
            */
            this.setReturn  =   function(thisChild,func)
                {
                    if(getKeyTap == 13) {
                        if(thisChild)
                            func(thisChild);
                    }
                }
            /*
            ** @description This will set the current DOM and add the select class
            ** @returns This will return the current DOM object
            */
            this.firstClick =   function()
                {
                    getChild    =   (getKeyTap == 38)? 'last' : 'first';
                    isSelected  =   getMenu.children('li:'+getChild+'-child');
                    isSelected.addClass('selected');
                    return isSelected;
                }
            /*
            ** @description This method will move the selection up and down
            ** @param isSelected [object] This is the current select DOM object
            ** @returns [object] this will return the current selected DOM object
            */
            this.currClick  =   function(isSelected)
                {
                    var setSpot =   'last';
    
                    if(getKeyTap == 38)
                        thisChild   =   isSelected.prev();
                    else if(getKeyTap == 40) {
                        thisChild   =   isSelected.next();
                        setSpot     =   'first';
                    }
    
                    if(!thisChild.hasClass('selectable'))
                        thisChild   =   getMenu.children("li:"+setSpot+"-child");
    
                    isSelected.removeClass('selected');
                    thisChild.addClass('selected');
                    return thisChild;
                }
    
            /*
            ** @description This will just run a function
            */
            this.doAction   =   function(func)
                {
                    return func();
                }
        }
    
    // When document is ready
    $(document).ready(function(){
        // Set container for this menu
        var isSelected  =   false;
        var qBox        =   $('input[name=q]');
        // Use the document object to listen for a key press
        $(this).keydown(function(e) {
            // See where the cursor is focused
            var isFocused   =   (e.target.nodeName == 'INPUT');
            // Start engine
            var sMenu       =   new keyAction($, $('ul'), e.keyCode);
            // If it's focused
            if(isFocused) {
                // Place text into field on return          
                sMenu.setReturn(isSelected,function(obj) {
                    qBox.val(isSelected.text());
                    // Submit form
                    $('#search').submit();
                });
    
                // If keys are allowed
                if(sMenu.keyAllowed()) {
                    isSelected  =   (!isSelected)? sMenu.firstClick(isSelected) : sMenu.currClick(isSelected);
                    // Copy the value of the selection into the input
                    sMenu.doAction(function(){
                        qBox.val(isSelected.text());
                    });
                }
            }
        });
        // On key up in the text field
        qBox.on('keyup',function(e){
            // If the key pressed is up or down arrow
            if(e.keyCode == 38 || e.keyCode == 40)
                // Don't do ajax call
                return false;
            // Run ajax
            $.ajax({
                url:"search/suggest.php",
                type:"get",
                data: $(this).serialize(),
                success:function(response) {
                    $('#dropdown_search').html(response);
                }
            });
        });
    });
    

    Style:

    .selected {
        background-color: #888;
    }
    

    HTML: Form

    <div class="form-container">
        <form id="search" name="search">
            <input type="text" name="q" id="query-value" placeholder="Search with Ajax...">
        </form>
    </div>
    <ul id="dropdown_search">
    </ul>
    

    HTML: Returned from ajax (just example)

    <li class="selectable">666554366</li>
    <li class="selectable">1174971318</li>
    <li class="selectable">1809433410</li>
    <li class="selectable">452149182</li>
    <li class="selectable">2024548770</li>
    
    点赞 评论 复制链接分享

相关推荐