js实现下拉框可输入
前言
众所周知,html默认的下拉框是无法输入值的,然后最新的办法是用datalist
和输入框绑定,但是很多浏览器不支持。然后还有很多框架提供的下拉框都是可输入的。但是公司的项目太老了,考虑到依赖性需要使用原生js去实现。
业务是这样,现在有一个输入框存在,需要在不改变这个输入框id的情况下让这个输入框能实现下拉框的效果。
代码实现
Js代码
我编写了一个函数用于接收元素id和下拉框的列表数据,函数内部需要完成下拉框的创建。
首先获取需要变成下拉框的输入框id,然后创建ul元素,然后为ul元素添加css属性,css代码在文章结尾。通过循环去创建li元素,在循环的内部不仅要创建li元素,还要为每个li设置data-key自定义属性作为下拉框的key。还需要为每个下拉框创建点击事件,也就是选中下拉框某个内容时,将li的内容赋值给input框,然后隐藏下拉框因为已经完成了选中操作。
hideOtherDropdowns隐藏未使用的下拉框,当我有多个下拉框的时候,点击第一个下拉框,再点击第二个下拉框的时候要让之前的下拉框隐藏,防止多个下拉框同时展开。
然后还需要为input框添加点击事件,当我点击input框的时候显示下拉列表,还需要为每个document添加点击事件,我点击其他dom的时候下拉框要隐藏,比如其他输入框,页面空白处。
最后将ul元素添加到input元素后面,并设置为relative定位模式。
window.addEventListener("DOMContentLoaded", function() {
var options = [
{ key: "1", value: "选项1" },
{ key: "2", value: "选项2" },
{ key: "3", value: "选项3" },
{ key: "4", value: "选项4" }
];
renderDropdown("test", options);
renderDropdown("test2", options);
});
function renderDropdown(id, options) {
var input = document.getElementById(id);
var dropdown = document.createElement("ul");
dropdown.classList.add("dropdown-options");
for (var i = 0; i < options.length; i++) {
var option = document.createElement("li");
option.textContent = options[i].value;
option.setAttribute("data-key", options[i].key);
option.addEventListener("click", function() {
input.value = this.textContent; // 将选中的值赋给 input
var selectedKey = this.getAttribute("data-key");
console.log("Selected key:", selectedKey);
dropdown.classList.remove("show");
console.log(input.value)
});
dropdown.appendChild(option);
}
function hideOtherDropdowns()
{
var otherDropdowns = document.querySelectorAll(".dropdown-options");
for (var j = 0; j < otherDropdowns.length; j++)
{ if (otherDropdowns[j] !== dropdown)
{
otherDropdowns[j].classList.remove("show");
}
}
}
input.addEventListener("click", function(e) {
hideOtherDropdowns();
//e.stopPropagation()的作用是阻止事件冒泡,使事件只在当前元素上触 发执行,不会继续传播到其他元素上。
e.stopPropagation();
dropdown.classList.toggle("show");
});
document.addEventListener("click", function() {
dropdown.classList.remove("show");
});
input.insertAdjacentElement("afterend", dropdown);
input.parentNode.style.position = "relative"; // 设置父元素的定位为相对定位
}
Css代码
.test {
position: relative;
width: 200px;
padding: 10px;
border: 1px solid #ccc;
cursor: pointer;
background-color: #fff;
}
.dropdown-options {
position: absolute;
left: 0;
width: auto;
max-height: 200px;
overflow-y: auto;
list-style-type: none;
margin: 0;
padding: 0;
background-color: #fff;
border: 1px solid #ccc;
border-top: none;
z-index: 999;
display: none;
}
.show{
display: block;
}
.dropdown-options li {
padding: 10px;
cursor: pointer;
}
.dropdown-options li:hover {
background-color: #f2f2f2;
}
Html代码
<input id="test" type="text" class="test" placeholder="请选择"/>
<br/>
<input id="test2" type="text" class="test" placeholder="请选择"/>