js實現下拉框可輸入 前言 眾所周知,html預設的下拉框是無法輸入值的,然後最新的辦法是用datalist和輸入框綁定,但是很多瀏覽器不支持。然後還有很多框架提供的下拉框都是可輸入的。但是公司的項目太老了,考慮到依賴性需要使用原生js去實現。 業務是這樣,現在有一個輸入框存在,需要在不改變這個輸入 ...
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="請選擇"/>