如何实现带搜索功能且可新增选项的下拉文本框?
实现带搜索/新增选项的下拉文本框方案
一、原生JavaScript实现(无依赖)
适合不想引入第三方库的场景,核心功能自己把控:
- 结构层:用
<input>做文本输入,<ul>承载下拉选项,额外通过逻辑生成「添加新选项」的入口 - 核心功能实现:
- 搜索过滤:监听输入框
input事件,实时匹配选项文本,隐藏不匹配项 - 新增选项:当输入内容不在现有选项中时,显示「添加‘xxx’」选项,点击后将内容加入下拉列表
- 下拉切换:点击输入框展开列表,点击外部区域收起
- 搜索过滤:监听输入框
代码示例
<div class="search-select-wrap"> <input type="text" id="searchInput" placeholder="搜索或输入新选项"> <ul id="optionsList" class="options-list"> <li class="option-item">选项1</li> <li class="option-item">选项2</li> <li class="option-item">选项3</li> </ul> </div>
.search-select-wrap { position: relative; width: 300px; } #searchInput { width: 100%; padding: 8px; box-sizing: border-box; border: 1px solid #ddd; } .options-list { position: absolute; top: calc(100% + 2px); left: 0; right: 0; border: 1px solid #ddd; border-top: none; list-style: none; padding: 0; margin: 0; max-height: 200px; overflow-y: auto; display: none; } .option-item { padding: 8px; cursor: pointer; } .option-item:hover { background-color: #f5f5f5; } .add-option { color: #007bff; border-top: 1px solid #eee; }
const input = document.getElementById('searchInput'); const optionsList = document.getElementById('optionsList'); let options = Array.from(optionsList.querySelectorAll('.option-item')); // 展开下拉列表 input.addEventListener('focus', () => { optionsList.style.display = 'block'; updateOptions(input.value); }); // 点击外部收起 document.addEventListener('click', (e) => { if (!input.contains(e.target) && !optionsList.contains(e.target)) { optionsList.style.display = 'none'; } }); // 实时搜索+新增选项逻辑 input.addEventListener('input', (e) => { const value = e.target.value.trim(); updateOptions(value); }); // 更新选项列表 function updateOptions(searchValue) { // 移除之前的临时添加项 const addOption = optionsList.querySelector('.add-option'); if (addOption) addOption.remove(); // 过滤显示匹配项 options.forEach(option => { option.style.display = option.textContent.includes(searchValue) ? 'block' : 'none'; }); // 输入内容不在现有选项中时,显示添加入口 if (searchValue && !options.some(opt => opt.textContent.trim() === searchValue)) { const newOption = document.createElement('li'); newOption.className = 'option-item add-option'; newOption.textContent = `添加“${searchValue}”`; newOption.addEventListener('click', () => { const permanentOption = document.createElement('li'); permanentOption.className = 'option-item'; permanentOption.textContent = searchValue; optionsList.insertBefore(permanentOption, optionsList.firstChild); options.push(permanentOption); input.value = searchValue; optionsList.style.display = 'none'; }); optionsList.appendChild(newOption); } } // 点击选项填充输入框 optionsList.addEventListener('click', (e) => { const target = e.target; if (target.classList.contains('option-item') && !target.classList.contains('add-option')) { input.value = target.textContent; optionsList.style.display = 'none'; } });
二、组件库快速实现
如果追求开发效率,推荐使用成熟组件库的现成组件,大部分支持搜索、自定义新增选项:
- React:使用
react-select的CreatableSelect组件,开启creatable属性即可支持新增,内置搜索过滤import CreatableSelect from 'react-select/creatable'; <CreatableSelect options={[{ value: 'option1', label: '选项1' }, { value: 'option2', label: '选项2' }]} placeholder="搜索或输入新选项" /> - Vue:使用
Element Plus的ElSelect配合自定义逻辑,或直接使用@vueform/multiselect,支持创建新选项 - 无框架场景:使用
Choices.js轻量级库,自带搜索、新增选项、样式自定义能力
内容的提问来源于stack exchange,提问作者MitchW
相关产品推荐
相关产品推荐

