65.9K
CodeProject 正在变化。 阅读更多。
Home

在用户键入时,自动选择(增量搜索、自动完成)下拉列表中的项目

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.35/5 (15投票s)

2006年8月6日

CPOL

2分钟阅读

viewsIcon

107559

downloadIcon

898

HTML 缺乏下拉列表的自动选择功能。熟悉桌面应用程序的用户期望浏览器在他们键入时从下拉列表中选择正确的项目。我尝试使用简单的 JavaScript 来解决这个问题。

Sample screenshot

引言

通常,HTML 不支持最近匹配。它总是将每个按键视为新的搜索的开始。但这没用。如果我输入 'C',它会跳转到以 C 开头的第一个项目;如果我立即输入 'O',它会跳转到以 'O' 开头的第一个项目。但在这个实现中,它会跳转到 'CO'。

如果用户拼写错误,用户可以使用退格键删除字符 'O' 并输入另一个字母来选择另一个项目。用户可以等待 3 秒钟开始新的搜索,或者使用退格键删除整个搜索键,或者 Shift+Delete 重新开始。

它找到最接近的匹配项。因此,它不需要以任何顺序排列。

  1. 只需将 .js 文件包含在目标 HTML 中
  2. <script language="JavaScript" src="dropdown.js"></script>
  3. 将这些事件添加到你的下拉字段
  4. onfocus="this.enteredText='';" onkeydown="return handleKey();" 
      onkeyup="event.cancelbubble=true;return false;" onkeypress="return selectItem();"

    例如

    <select name="test" onfocus="this.enteredText='';" onkeydown="return handleKey();" 
      onkeyup="event.cancelbubble=true;return false;" onkeypress="return selectItem();">
    • onfocus 重置搜索文本。
    • onkeydown 处理某些键(左、右、上、下、Shift、Delete、Backspace)并采取适当的操作。
    • onkeypress 处理从列表中选择项目。
    • onkeyup 忽略该事件,因为 onkeypress 已经处理了按键。
  5. 使用 IE 打开 HTML 文件。
  6. 输入 'a',它会带你到以 'a' 开头的第一个项目。然后,输入 'b';这将带你到以 'ab' 开头的第一个项目。这使用了一种最近匹配算法。因此,列表不需要以任何顺序排列。
    1. 用户可以在下拉列表中搜索字符串。
    2. 它自动选择以搜索键开头的列表项。
    3. 用户可以使用退格键删除搜索键中当前索引之前的字符。
    4. 用户可以使用 Delete 按钮删除搜索键中当前索引之后的字符。
    5. 用户可以使用左右箭头键在搜索键上来回移动,并使用 Delete 或 Backspace 删除字符;脚本将自动找到列表中的项目,或从当前索引输入新字符。
    6. 按下 Shift 和 Delete 键将删除搜索键并重新开始搜索。
    7. 用户可以在 Windows 状态栏上看到搜索键。它还显示当前索引。

我也添加了 Hugh Nelson 的建议,以便每个人都可以使用。如果你想更改页面中的所有下拉列表以具有此功能,请在 onload 事件中调用以下代码

function setSelectEvents() {
    // set javascript event attributes
    // for all select items in the current page
    var selects = document.getElementsByTagName("select");
    var arrOnfocus = new Array(); // array of onfocus functions
    var arrOnkeydown = new Array(); // array of onkeydown functions
    var arrOnkeyup = new Array(); // array of onkeyup functions
    var arrOnkeypress = new Array(); // array of onkeypress functions

    for (var i = 0; i < selects.length; i++) {
        // we need to ensure that
        // we don't overwrite any existing function

        // save index to array as an element attribute
        // (using i directly did not work)
        selects[i].title = i;

        // onfocus
        if(typeof(selects[i].onfocus) == 'function') {
        // there is a pre-existing function
            // save pre-existing function
            arrOnfocus[selects[i].title] = selects[i].onfocus;
            selects[i].onfocus = 
              function() { arrOnfocus[this.title](); this.enteredText=''; }
              // set event to call our code plus the pre-existing function
        }
        else { // there is no pre-existing function
            selects[i].onfocus = function() { this.enteredText=''; }
        }

        // onkeydown
        if(typeof(selects[i].onkeydown) == 'function') {
        // there is a pre-existing function
            // save pre-existing function
            arrOnkeydown[selects[i].title] = selects[i].onkeydown;
            selects[i].onkeydown = 
              function() { arrOnkeydown[this.title](); return handleKey(); }
              // set event to call our code plus the pre-existing function
        }
        else { // there is no pre-existing function
            selects[i].onkeydown = function() { return handleKey(); }
        }

        // onkeyup
        if(typeof(selects[i].onkeyup) == 'function') {
        // there is a pre-existing function
            // save pre-existing function
            arrOnkeyup[selects[i].title] = selects[i].onkeyup;
            selects[i].onkeyup = 
              function() { arrOnkeyup[this.title](); 
                           event.cancelbubble=true;return false; }
              // set event to call our code plus the pre-existing function
        }
        else { // there is no pre-existing function
            selects[i].onkeyup = 
              function() { event.cancelbubble=true;return false; }
        }

        // onkeypress
        if(typeof(selects[i].onkeypress) == 'function') {
        // there is a pre-existing function
            // save pre-existing function
            arrOnkeypress[selects[i].title] = selects[i].onkeypress;
            selects[i].onkeypress = 
               function() { arrOnkeypress[this.title](); return selectItem(); }
               // set event to call our code plus the pre-existing function
        }
        else { // there is no pre-existing function
            selects[i]. &#246;nkeypress = function() { return selectItem(); }
        }
    }
}
© . All rights reserved.