dougan4663 2016-07-21 05:10 采纳率: 0%
浏览 52
已采纳

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

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 2016-07-21 18:52
    关注

    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>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 安装 opencv4nodejs 报错
  • ¥15 adb push异常 adb: error: 1409-byte write failed: Invalid argument
  • ¥15 nginx反向代理获取ip,java获取真实ip
  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥15 复杂网络,变滞后传递熵,FDA
  • ¥20 csv格式数据集预处理及模型选择
  • ¥15 部分网页页面无法显示!