使用向上和向下箭头进行自动完成搜索

时间:2013-07-23 12:53:53

标签: javascript jquery html

在google 中有很多关于自动完成jquery的例子“例如搜索像搜索jquery的facebook”

但我找不到任何显示如何使用向上和向下箭头键向下滚动结果。

我的“结果”div包含结果列表,如下所示:

那么我如何使用向上和向下箭头键以及下面的代码向下滚动我的结果?

<form id="search-form" method="get" action="search.php">
    <input class="search-terms" type="text" value="Search" autocomplete="off" name="resultsFor" /> 
    <input class="submit-search" type="submit" value="go" /></form>
    <div id="results" class="shadow" style="display: none;">
      <h4 class="tophit-title" style="background-color: #4AABD8">Top Hits</h4>
      <ul id="tophit-list">
        <li>a target=&quot;_blank&quot; href=&quot;url.com?act=view&amp;id=4 &quot;&gt; 
        <img width="62" height="62" alt="img sample" src="http://127.0.0.1/sample.JPG" /> 
        <span>a carton o 
        <b>f</b> mil</span></li>
        <li>a target=&quot;_blank&quot; href=&quot;url.com?act=view&amp;id=2 &quot;&gt; 
        <img width="62" height="62" alt="img sample2" src="http://127.0.0.1/sample2.JPG" /> 
        <span>a carton o 
        <b>f</b> mil</span></li>
      </ul>
    </div>

这是我的jquery函数:

$(".search-terms").keyup(function (e) {
    var searchbox = $(this);

    switch (e.keyCode) {

        case 38:
            alert("UP");
            break;
        case 40:
            alert("DOWN");
            break;
    }
});

2 个答案:

答案 0 :(得分:4)

这是使用箭头键在列表中移动的基本功能。

$("ul").keydown(function (e) {
    var searchbox = $(this);
    switch (e.which) {
        case 40:
            $('li:not(:last-child).selected').removeClass('selected')
                 .next().addClass('selected');
            break;
        case 38:
            $('li:not(:first-child).selected').removeClass('selected')
                 .prev().addClass('selected');
            break;
    }
});

我们可以将此应用于带有输入的表单以移动所选项目。重点需要留在输入上才能实现

$(".search-terms").keydown(function(e) {
  switch (e.which) {
    case 40:
      e.preventDefault(); // prevent moving the cursor
      $('li:not(:last-child).selected').removeClass('selected')
        .next().addClass('selected');
      break;
    case 38:
      e.preventDefault(); // prevent moving the cursor
      $('li:not(:first-child).selected').removeClass('selected')
        .prev().addClass('selected');
      break;
  }
});

$('.search-terms').keyup(function() {
  if (this.value.length >= 1) {
    $('#results').show();
  } else {
    $('#results').hide();
  }
})
.selected {
  color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="search-form" method="get" action="search.php">
  <input class="search-terms" type="text" value="" placeholder='Search' autocomplete="off" name="resultsFor" />
  <input class="submit-search" type="submit" value="go" /></form>

<div id="results" style="display: none;">
  <h4 class="tophit-title" style="background-color: #4AABD8">Top Hits</h4>
  <ul tabindex='1'>
    <li class='selected'>ok</li>
    <li>ok</li>
    <li>ok</li>
    <li>ok</li>
    <li>ok</li>
  </ul>
</div>

答案 1 :(得分:0)

在我参与的其中一个项目中,我回忆起制作类似的东西。我挖出了代码供您检查(DSL代表动态搜索列表):

var dslTimer = [];
var dslData = [];
var dslControls = [];
var dslSelected = [];
var dslSelectedIndex = 0;

var callBackFunction;

function addDsl(inputField, dslPlaceHolder, dslUrl, maxDepth, callback, countryLimitation) {
    var dslIndex = dslControls.length + 1;
    dslControls[dslIndex] = [inputField, dslPlaceHolder, dslUrl, maxDepth, countryLimitation];
    callBackFunction = callback;

    $('#' + inputField).keyup(function(e) {
        var key = e.keyCode;
        if (key == '13') {
            if ($('#' + dslControls[dslIndex][1]).hasClass('hidden') && $('#' + inputField).val().length > 0) {
                if (callback == null) {
                    $('#' + dslControls[dslIndex][1]).closest('form').submit();
                }
                else {
                    callback();
                }
            }
            else {
                $('#' + dslControls[dslIndex][1]).addClass('hidden');
            }
        } else if (key == '38') {
            //Up key
            $('#' + dslControls[dslIndex][1] + ' ul li:nth-child(' + dslSelectedIndex + ') a').removeClass('highlight');
            dslSelectedIndex -= 1;
            if (dslSelectedIndex < 0) {
                dslSelectedIndex = $('#' + dslControls[dslIndex][1] + ' ul li').length;
            }
            $('#' + dslControls[dslIndex][1] + ' ul li:nth-child(' + dslSelectedIndex + ') a').addClass('highlight');

            var str = $('#' + dslControls[dslIndex][1] + ' ul li:nth-child(' + dslSelectedIndex + ') a').text();
            if (str != null && str != "") {
                $('#' + dslControls[dslIndex][0]).val(str);
            }
        } else if (key == '40') {
            //Down key
            $('#' + dslControls[dslIndex][1] + ' ul li:nth-child(' + dslSelectedIndex + ') a').removeClass('highlight');
            dslSelectedIndex += 1
            if (dslSelectedIndex > $('#' + dslControls[dslIndex][1] + ' ul li').length) {
                dslSelectedIndex = 0;
            }
            $('#' + dslControls[dslIndex][1] + ' ul li:nth-child(' + dslSelectedIndex + ') a').addClass('highlight');

            var str = $('#' + dslControls[dslIndex][1] + ' ul li:nth-child(' + dslSelectedIndex + ') a').text();
            if (str != null && str != "") {
                $('#' + dslControls[dslIndex][0]).val(str);
            }
        } else {
            var input = $('#' + dslControls[dslIndex][0]).val();

            if (input.length >= 2) {
                window.clearTimeout(dslTimer[dslIndex]);
                dslTimer[dslIndex] = window.setTimeout('doDsl(' + dslIndex + ')', 100);
            }
            else {
                $('#' + dslControls[dslIndex][1]).addClass('hidden');
            }
        }
    });
    $('#' + inputField).blur(function(e) {
        window.setTimeout('blurDsl(' + dslIndex + ')', 500);
    });

    return dslIndex;
}

function doDsl(dslIndex) {
    getDsl(dslIndex, $('#' + dslControls[dslIndex][0]).val());
}

function getDsl(dslIndex, searchstring) {
    if (searchstring.length < 2) {
        return;
    }

    var postData = { 'input': searchstring, 'maxDepth': dslControls[dslIndex][3] };
    if (typeof (dslControls[dslIndex][4]) != 'undefined' || dslControls[dslIndex][4] != null) {
        postData.countryId = dslControls[dslIndex][4].val();
    }

    $.ajax({
        type: 'POST',
        url: dslControls[dslIndex][2],
        data: postData,
        dataType: "json",
        contentType: "application/x-www-form-urlencoded",
        timeout: 60000,
        global : false,
        success: function (data) {
            (data.length > 0)
                ? showDsl(dslIndex, data)
                : blurDsl(dslIndex);
        }
    });
}

function showDsl(dslIndex, data) {
    dslData[dslIndex] = data;
    dslSelected[dslIndex] = null;

    var htmlString = '<ul>';
    var searchText = $('#' + dslControls[dslIndex][0]).val().ignoreAccent();

    $.each(data, function(i, item) {
        var text = item.Text;
        var accentlessText = item.AccentlessText.Value;

        var boldStart = accentlessText.toLowerCase().indexOf(searchText.toLowerCase());
        while (boldStart > -1 && searchText.length > 0) {
            text = text.substring(0, boldStart) + '<strong>' + text.substring(boldStart, (boldStart + searchText.length)) + '</strong>' + text.substring((boldStart + searchText.length), text.length);

            boldStart = accentlessText.toLowerCase().indexOf(searchText.toLowerCase(), (boldStart + 17 + searchText.length));
        }
        htmlString += '<li><a href="javascript:void(0)" onmousedown="selectDsl(' + dslIndex + ', \'' + item.Id + '\')" tabindex="' + (1000 + i) + '">' + text + '</a></li>';
    });
    htmlString += '</ul>';

    $('#' + dslControls[dslIndex][1] + ' ul').replaceWith(htmlString);

    dslSelectedIndex = 0;
    if (data.length > 0) {
        $('#' + dslControls[dslIndex][1]).removeClass('hidden');
    }
}

function selectDsl(dslIndex, id) {
    $('#' + dslControls[dslIndex][1]).addClass('hidden');
    $.each(dslData[dslIndex], function(i, item) {
        if (item.Id == id) {
            $('#' + dslControls[dslIndex][0]).val(item.Text);
            dslSelected[dslIndex] = item;
            if (callBackFunction != null) {
                callBackFunction();
            }
        }
    });
}

function blurDsl(dslIndex) {
    $('#' + dslControls[dslIndex][1]).addClass('hidden');
}

// Source: https://github.com/zimny/accentless
(function () {
    if (String.prototype.ignoreAccent) return;

    var AccentCharCodesTable = {
        "a": [224, 229],
        "A": [192, 198],
        "c": [231, 231],
        "C": [199, 199],
        "e": [231, 235],
        "E": [200, 203],
        "i": [236, 239],
        "I": [204, 208],
        "n": [241, 241],
        "N": [209, 209],
        "o": [242, 246],
        "O": [209, 214],
        "s": [353, 353],
        "S": [352, 352],
        "u": [248, 252],
        "U": [216, 220],
        "y": [253, 253],
        "Y": [221, 221],
        "z": [382, 382],
        "Z": [381, 381]
    };

    String.prototype.ignoreAccent = function() {
        var i, currentCharCode, char, str = this.split("");

        for (i = 0; i < str.length; i++) {
            currentCharCode = str[i].charCodeAt(0);
            if (currentCharCode < 192) continue;
            for (char in AccentCharCodesTable) {
                if (AccentCharCodesTable.hasOwnProperty(char)) {
                    if (currentCharCode >= AccentCharCodesTable[char][0] && currentCharCode <= AccentCharCodesTable[char][1]) {
                        str[i] = char;
                        break;
                    }
                }
            }
        }
        return str.join("");
    };
})();