Javascript 如何创建类似于 Google 的建议下拉列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6169659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create a suggestion drop-down list like Google's?
提问by RonLugge
It's a theoretical question at this point in time, but something I'm probably going to want to do long-term.
目前,这是一个理论上的问题,但我可能会长期想做一些事情。
When you go to google.com and start typing a search, it'll provide you with suggestions in a little drop down menu. I'm reasonably certain that they use AJAX to send what you've typed and get a list of possible suggestions back. What I'm trying to figure out is how they actually display that list. It looks like a simple <select> drop down list, just without the actual select box at the top. There is zero doubt in my mind that it's something as stupidly simple as a CSS trick that divides the select box from drop-down list it produces or an input type other than select, but I'm drawing a blank.
当您访问 google.com 并开始输入搜索内容时,它会在一个小下拉菜单中为您提供建议。我相当确定他们使用 AJAX 发送您输入的内容并返回可能的建议列表。我想弄清楚的是他们实际上是如何显示该列表的。它看起来像一个简单的 <select> 下拉列表,只是顶部没有实际的选择框。在我看来,这是一件愚蠢的事情,就像将选择框与它生成的下拉列表或选择以外的输入类型分开的 CSS 技巧一样愚蠢,但我正在绘制一个空白。
采纳答案by Anze Jarni
okay, so you got multiple posibilities, you can use a select dropdown and draw it exactly underneath the input typed text, which is ment for typing in the keyword. Off course in CSS it needs to be absolute positioned with a lower z-index than the input for text.
好的,所以您有多种可能性,您可以使用选择下拉列表并将其准确地绘制在输入的输入文本下方,这是输入关键字的必要条件。当然,在 CSS 中,它需要绝对定位,z-index 低于文本输入。
the other, more complex example is that you a draw a unordered list which is styled like a dropdown. If you use this one, you can for example also load images (icons) with the ordinary text suggestion. For this example you need to position the ul beneath the input for text, create css hover effects for currently selected il and create click event on each il, which fills up the text input with clicked keyword and hides the unordered list.
另一个更复杂的例子是你绘制一个无序列表,它的样式类似于下拉列表。如果你使用这个,你还可以加载带有普通文本建议的图像(图标)。对于本示例,您需要将 ul 放置在文本输入下方,为当前选定的 il 创建 css 悬停效果,并在每个 il 上创建单击事件,这会使用 clicked 关键字填充文本输入并隐藏无序列表。
I hope that explains your question.
我希望这能解释你的问题。
回答by Anze Jarni
You can use jQuery AutoComplete -
您可以使用 jQuery 自动完成 -
The idea is that you fire a JavaScript event onKeyUp. This event should post an ajax request containing the current value of the input you are writing on.
这个想法是你在KeyUp 上触发一个JavaScript 事件。此事件应发布一个 ajax 请求,其中包含您正在写入的输入的当前值。
From there the PHP checks the database for the keyword you written, and if it is it returns the results back to the JavaScript.
从那里,PHP 检查数据库中是否有您编写的关键字,如果是,则将结果返回给 JavaScript。
JS checks the result of the ajax request and fills anything returned from ajax into an absolute positioned select.
JS 检查 ajax 请求的结果,并将 ajax 返回的任何内容填充到绝对定位的 select 中。
The absolute positioned select has an onClick event that fills the clicked value from the select into the text input you are writting to.
绝对定位选择有一个 onClick 事件,该事件将选择中的单击值填充到您要写入的文本输入中。
Excuse my English, but I'm trying hard to explain.
请原谅我的英语,但我正在努力解释。
回答by Shivam Sharma
I am pretty late to answer. But W3schools has done a marvellous job for this.
我很晚才回答。但是 W3schools 在这方面做得非常出色。
Just HTML, CSS, Pure JavaScript nothing else. Must watch this.
只是 HTML、CSS、纯 JavaScript,别无他物。必须看这个。
Link to this: W3Schools Auto Complete
链接到此:W3Schools 自动完成
In case of link removal, I am copy pasting the code here.
在链接删除的情况下,我在这里复制粘贴代码。
function autocomplete(inp, arr) {
/*the autocomplete function takes two arguments,
the text field element and an array of possible autocompleted values:*/
var currentFocus;
/*execute a function when someone writes in the text field:*/
inp.addEventListener("input", function(e) {
var a, b, i, val = this.value;
/*close any already open lists of autocompleted values*/
closeAllLists();
if (!val) { return false;}
currentFocus = -1;
/*create a DIV element that will contain the items (values):*/
a = document.createElement("DIV");
a.setAttribute("id", this.id + "autocomplete-list");
a.setAttribute("class", "autocomplete-items");
/*append the DIV element as a child of the autocomplete container:*/
this.parentNode.appendChild(a);
/*for each item in the array...*/
for (i = 0; i < arr.length; i++) {
/*check if the item starts with the same letters as the text field value:*/
if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
/*create a DIV element for each matching element:*/
b = document.createElement("DIV");
/*make the matching letters bold:*/
b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
b.innerHTML += arr[i].substr(val.length);
/*insert a input field that will hold the current array item's value:*/
b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
/*execute a function when someone clicks on the item value (DIV element):*/
b.addEventListener("click", function(e) {
/*insert the value for the autocomplete text field:*/
inp.value = this.getElementsByTagName("input")[0].value;
/*close the list of autocompleted values,
(or any other open lists of autocompleted values:*/
closeAllLists();
});
a.appendChild(b);
}
}
});
/*execute a function presses a key on the keyboard:*/
inp.addEventListener("keydown", function(e) {
var x = document.getElementById(this.id + "autocomplete-list");
if (x) x = x.getElementsByTagName("div");
if (e.keyCode == 40) {
/*If the arrow DOWN key is pressed,
increase the currentFocus variable:*/
currentFocus++;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 38) { //up
/*If the arrow UP key is pressed,
decrease the currentFocus variable:*/
currentFocus--;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 13) {
/*If the ENTER key is pressed, prevent the form from being submitted,*/
e.preventDefault();
if (currentFocus > -1) {
/*and simulate a click on the "active" item:*/
if (x) x[currentFocus].click();
}
}
});
function addActive(x) {
/*a function to classify an item as "active":*/
if (!x) return false;
/*start by removing the "active" class on all items:*/
removeActive(x);
if (currentFocus >= x.length) currentFocus = 0;
if (currentFocus < 0) currentFocus = (x.length - 1);
/*add class "autocomplete-active":*/
x[currentFocus].classList.add("autocomplete-active");
}
function removeActive(x) {
/*a function to remove the "active" class from all autocomplete items:*/
for (var i = 0; i < x.length; i++) {
x[i].classList.remove("autocomplete-active");
}
}
function closeAllLists(elmnt) {
/*close all autocomplete lists in the document,
except the one passed as an argument:*/
var x = document.getElementsByClassName("autocomplete-items");
for (var i = 0; i < x.length; i++) {
if (elmnt != x[i] && elmnt != inp) {
x[i].parentNode.removeChild(x[i]);
}
}
}
/*execute a function when someone clicks in the document:*/
document.addEventListener("click", function (e) {
closeAllLists(e.target);
});
}
/*An array containing all the country names in the world:*/
var countries = ["Afghanistan","Albania","Algeria","Andorra","Angola","Anguilla","Antigua & Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia & Herzegovina","Botswana","Brazil","British Virgin Islands","Brunei","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Canada","Cape Verde","Cayman Islands","Central Arfrican Republic","Chad","Chile","China","Colombia","Congo","Cook Islands","Costa Rica","Cote D Ivtheitroade","Croatia","Cuba","Curacao","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia","Ethiopia","Falkland Islands","Faroe Islands","Fiji","Finland","France","French Polynesia","French West Indies","Gabon","Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guam","Guatemala","Guernsey","Guinea","Guinea Bissau","Guyana","Haiti","Honduras","Hong Kong","Hungary","Iceland","India","Indonesia","Iran","Iraq","Ireland","Isle of Man","Israel","Italy","Jamaica","Japan","Jersey","Jordan","Kazakhstan","Kenya","Kiribati","Kosovo","Kuwait","Kyrgyzstan","Laos","Latvia","Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg","Macau","Macedonia","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Mauritania","Mauritius","Mexico","Micronesia","Moldova","Monaco","Mongolia","Montenegro","Montserrat","Morocco","Mozambique","Myanmar","Namibia","Nauro","Nepal","Netherlands","Netherlands Antilles","New Caledonia","New Zealand","Nicaragua","Niger","Nigeria","North Korea","Norway","Oman","Pakistan","Palau","Palestine","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Poland","Portugal","Puerto Rico","Qatar","Reunion","Romania","Russia","Rwanda","Saint Pierre & Miquelon","Samoa","San Marino","Sao Tome and Principe","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","Solomon Islands","Somalia","South Africa","South Korea","South Sudan","Spain","Sri Lanka","St Kitts & Nevis","St Lucia","St Vincent","Sudan","Suriname","Swaziland","Sweden","Switzerland","Syria","Taiwan","Tajikistan","Tanzania","Thailand","Timor L'Este","Togo","Tonga","Trinidad & Tobago","Tunisia","Turkey","Turkmenistan","Turks & Caicos","Tuvalu","Uganda","Ukraine","United Arab Emirates","United Kingdom","United States of America","Uruguay","Uzbekistan","Vanuatu","Vatican City","Venezuela","Vietnam","Virgin Islands (US)","Yemen","Zambia","Zimbabwe"];
/*initiate the autocomplete function on the "myInput" element, and pass along the countries array as possible autocomplete values:*/
autocomplete(document.getElementById("myInput"), countries);
* {
box-sizing: border-box;
}
body {
font: 16px Arial;
}
.autocomplete {
/*the container must be positioned relative:*/
position: relative;
display: inline-block;
}
input {
border: 1px solid transparent;
background-color: #f1f1f1;
padding: 10px;
font-size: 16px;
}
input[type=text] {
background-color: #f1f1f1;
width: 100%;
}
input[type=submit] {
background-color: DodgerBlue;
color: #fff;
cursor: pointer;
}
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
/*position the autocomplete items to be the same width as the container:*/
top: 100%;
left: 0;
right: 0;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
}
.autocomplete-items div:hover {
/*when hovering an item:*/
background-color: #e9e9e9;
}
.autocomplete-active {
/*when navigating through the items using the arrow keys:*/
background-color: DodgerBlue !important;
color: #ffffff;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>Autocomplete</h2>
<p>Start typing:</p>
<!--Make sure the form has the autocomplete function switched off:-->
<form autocomplete="off" action="/action_page.php">
<div class="autocomplete" style="width:300px;">
<input id="myInput" type="text" name="myCountry" placeholder="Country">
</div>
<input type="submit">
</form>
</body>
</html>