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






4.35/5 (15投票s)
HTML 缺乏下拉列表的自动选择功能。熟悉桌面应用程序的用户期望浏览器在他们键入时从下拉列表中选择正确的项目。我尝试使用简单的 JavaScript 来解决这个问题。
引言
通常,HTML 不支持最近匹配。它总是将每个按键视为新的搜索的开始。但这没用。如果我输入 'C',它会跳转到以 C 开头的第一个项目;如果我立即输入 'O',它会跳转到以 'O' 开头的第一个项目。但在这个实现中,它会跳转到 'CO'。
如果用户拼写错误,用户可以使用退格键删除字符 'O' 并输入另一个字母来选择另一个项目。用户可以等待 3 秒钟开始新的搜索,或者使用退格键删除整个搜索键,或者 Shift+Delete 重新开始。
它找到最接近的匹配项。因此,它不需要以任何顺序排列。
- 只需将 .js 文件包含在目标 HTML 中
- 将这些事件添加到你的下拉字段
onfocus
重置搜索文本。onkeydown
处理某些键(左、右、上、下、Shift、Delete、Backspace)并采取适当的操作。onkeypress
处理从列表中选择项目。onkeyup
忽略该事件,因为onkeypress
已经处理了按键。- 使用 IE 打开 HTML 文件。
- 输入 'a',它会带你到以 'a' 开头的第一个项目。然后,输入 'b';这将带你到以 'ab' 开头的第一个项目。这使用了一种最近匹配算法。因此,列表不需要以任何顺序排列。
- 用户可以在下拉列表中搜索字符串。
- 它自动选择以搜索键开头的列表项。
- 用户可以使用退格键删除搜索键中当前索引之前的字符。
- 用户可以使用 Delete 按钮删除搜索键中当前索引之后的字符。
- 用户可以使用左右箭头键在搜索键上来回移动,并使用 Delete 或 Backspace 删除字符;脚本将自动找到列表中的项目,或从当前索引输入新字符。
- 按下 Shift 和 Delete 键将删除搜索键并重新开始搜索。
- 用户可以在 Windows 状态栏上看到搜索键。它还显示当前索引。
<script language="JavaScript" src="dropdown.js"></script>
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();">
我也添加了 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]. önkeypress = function() { return selectItem(); }
}
}
}