js 实现combox
实现基本的 ComboBox 功能
使用 HTML、CSS 和 JavaScript 创建一个简单的 ComboBox,包含输入框和下拉选项列表:
<div class="combo-box">
<input type="text" class="combo-input" placeholder="Select an option">
<ul class="combo-options">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
</div>
<style>
.combo-box {
position: relative;
width: 200px;
}
.combo-input {
width: 100%;
padding: 8px;
}
.combo-options {
position: absolute;
width: 100%;
margin: 0;
padding: 0;
list-style: none;
border: 1px solid #ddd;
max-height: 200px;
overflow-y: auto;
display: none;
}
.combo-options li {
padding: 8px;
cursor: pointer;
}
.combo-options li:hover {
background-color: #f5f5f5;
}
</style>
<script>
const input = document.querySelector('.combo-input');
const options = document.querySelector('.combo-options');
input.addEventListener('focus', () => {
options.style.display = 'block';
});
input.addEventListener('blur', () => {
setTimeout(() => {
options.style.display = 'none';
}, 200);
});
options.querySelectorAll('li').forEach(option => {
option.addEventListener('click', () => {
input.value = option.textContent;
options.style.display = 'none';
});
});
</script>
添加键盘导航支持
增强 ComboBox 的交互性,支持键盘上下箭头选择和回车确认:
input.addEventListener('keydown', (e) => {
const items = options.querySelectorAll('li');
let currentIndex = Array.from(items).findIndex(item =>
item.classList.contains('selected')
);
if (e.key === 'ArrowDown') {
e.preventDefault();
currentIndex = (currentIndex + 1) % items.length;
updateSelection(items, currentIndex);
} else if (e.key === 'ArrowUp') {
e.preventDefault();
currentIndex = (currentIndex - 1 + items.length) % items.length;
updateSelection(items, currentIndex);
} else if (e.key === 'Enter') {
e.preventDefault();
if (currentIndex >= 0) {
input.value = items[currentIndex].textContent;
options.style.display = 'none';
}
}
});
function updateSelection(items, index) {
items.forEach(item => item.classList.remove('selected'));
items[index].classList.add('selected');
items[index].scrollIntoView({ block: 'nearest' });
}
实现过滤功能
为 ComboBox 添加输入时实时过滤选项的功能:
input.addEventListener('input', () => {
const searchTerm = input.value.toLowerCase();
const items = options.querySelectorAll('li');
items.forEach(item => {
const text = item.textContent.toLowerCase();
item.style.display = text.includes(searchTerm) ? 'block' : 'none';
});
options.style.display = 'block';
});
使用数据动态生成选项
从数据数组动态生成 ComboBox 选项:
const data = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'];
function populateOptions() {
options.innerHTML = '';
data.forEach(item => {
const li = document.createElement('li');
li.textContent = item;
options.appendChild(li);
});
options.querySelectorAll('li').forEach(option => {
option.addEventListener('click', () => {
input.value = option.textContent;
options.style.display = 'none';
});
});
}
populateOptions();
添加自定义事件
为 ComboBox 添加自定义事件处理:
function triggerEvent(name, detail) {
const event = new CustomEvent(name, { detail });
input.dispatchEvent(event);
}
input.addEventListener('change', () => {
triggerEvent('combochange', { value: input.value });
});
// 使用示例
input.addEventListener('combochange', (e) => {
console.log('Selected value changed to:', e.detail.value);
});
完整组件封装
将 ComboBox 封装为可重用的类:
class ComboBox {
constructor(container, options) {
this.container = container;
this.options = options.data || [];
this.init();
}
init() {
this.container.innerHTML = `
<input type="text" class="combo-input" placeholder="${this.options.placeholder || 'Select'}">
<ul class="combo-options"></ul>
`;
this.input = this.container.querySelector('.combo-input');
this.optionsList = this.container.querySelector('.combo-options');
this.renderOptions();
this.setupEvents();
}
renderOptions() {
this.optionsList.innerHTML = this.options
.map(item => `<li>${item}</li>`)
.join('');
}
setupEvents() {
// 添加之前的事件处理代码
}
}
// 使用示例
const combo = new ComboBox(document.getElementById('combo-container'), {
data: ['Red', 'Green', 'Blue'],
placeholder: 'Select a color'
});






