Javascript 自动建议下拉列表未使用上/下箭头键进行选择

Javascript 自动建议下拉列表未使用上/下箭头键进行选择,javascript,php,jquery,ajax,Javascript,Php,Jquery,Ajax,我的网站有一个非常基本的自动建议功能,每当用户在我的搜索输入中输入内容时,该功能就会运行 它的功能应该有点像谷歌搜索自动建议,而且它确实有点像谷歌搜索自动建议。但是,当返回一些建议时,如果用户点击键盘上的一个箭头,它将不会选择任何建议 这是我的JS(用于选择建议): $(document).ready(function(){ var $result = $('li'); $('input').keydown(function(e){ var key = e.ke

我的网站有一个非常基本的自动建议功能,每当用户在我的搜索输入中输入内容时,该功能就会运行

它的功能应该有点像谷歌搜索自动建议,而且它确实有点像谷歌搜索自动建议。但是,当返回一些建议时,如果用户点击键盘上的一个箭头,它将不会选择任何建议

这是我的JS(用于选择建议):

$(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');
    });
});
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();
}
<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>
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 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);
            }
        });
    });
});
.selected {
    background-color: #888;
}
这是我的Ajax:

$(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');
    });
});
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();
}
<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>
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 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);
            }
        });
    });
});
.selected {
    background-color: #888;
}
最基本的HTML:

$(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');
    });
});
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();
}
<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>
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 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);
            }
        });
    });
});
.selected {
    background-color: #888;
}

最后,我的PHP:

$(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');
    });
});
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();
}
<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>
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 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);
            }
        });
    });
});
.selected {
    background-color: #888;
}
if(isset($\u GET['q'])){
$results='';
$query=trim($_GET['q']);
如果(!empty($query)){
$stmt=$conn->prepare(“从autosuggest中选择标题、流行度,其中关键字:query或title-LIKE:query ORDER BY popularity desc LIMIT 7”);
$query=$query.'%';
$stmt->bindParam(':query',$query);
$stmt->execute();
$count=$stmt->rowCount();
$i=0;
如果($count>0){
while($row=$stmt->fetch(PDO::fetch_OBJ)){
$title=$row->title;
$popularity=$row->popularity;
$i++;
$results.='
  • ”.$title.
  • ”; } } } } 打印($results);

    我觉得问题似乎出在我的“selection jQuery”中,然而,我已经确保对所有内容进行了三次检查,但我似乎找不到任何会阻止该功能工作的内容。

    我不确定Google是如何工作的,但我相信您正在尝试执行类似以下脚本的操作。您应该能够将其应用于返回的下拉菜单。它检查光标是否聚焦在输入字段中。如果是,则激活下面的键码脚本:

    jsFiddle:

    JavaScript:

    $(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');
        });
    });
    
    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();
    }
    
    <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>
    
    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 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);
                }
            });
        });
    });
    
    .selected {
        background-color: #888;
    }
    
    风格:

    $(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');
        });
    });
    
    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();
    }
    
    <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>
    
    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 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);
                }
            });
        });
    });
    
    .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:从ajax返回(仅为示例)

  • 666554366
  • 1174971318
  • 1809433410
  • 452149182
  • 2024548770

  • 当您已经在使用jQuery时,您却在使用自己的AJAX,这让我发笑。@PHPglue这是我第一次使用AJAX。。我使用的是一个网站的修改版,我还在学习中,为什么不使用自动完成的texbox?@MArgusChopinGyver我更喜欢使用我自己的代码。我觉得这是一种更好的学习方式,而不仅仅是使用预设功能。因此,您可以单击所选内容,但也可以上下键,对吗?嗨,谢谢您的回答!但是,我在调试代码时遇到了一些麻烦,无法找到一种方法,这样他们就只能在选择输入时选择一个建议。你认为你能编辑你的代码一点,以更好地适合我的吗?我现在对JavaScriptTry还是很陌生,它应该是您所需要的。请看小提琴演示。你必须把注意力集中在输入上,它才能工作。嗨,所以我检查了一下这是否有效,但是,一旦选择了某个东西,它就会出现一些小故障并立即取消选择。你知道为什么会这样吗?干杯你有公共页面来查看异常吗?不幸的是,我只能向你展示我的代码:/看看那里,因为这是所有必要的东西