为自动完成搜索添加搜索按钮操作
在网页开发中,自动完成搜索功能可以提升用户输入效率,但很多时候我们需要搭配独立的搜索按钮,让用户可以主动触发搜索操作,而不是仅仅依赖输入完成后的自动跳转。本文将介绍如何在HTML和相关脚本中实现带搜索按钮的自动完成搜索功能。
基础HTML结构搭建
首先我们需要构建搜索区域的基础结构,包含一个输入框用于输入搜索内容,一个按钮用于触发搜索,还有一个容器用来展示自动完成的候选列表。注意这里提到的<input>标签和<button>标签都需要正确书写,同时自动完成候选列表默认隐藏,只有输入内容时才会显示。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>带按钮的自动完成搜索</title>
<style>
.search-container {
width: 500px;
margin: 50px auto;
position: relative;
}
.search-input-wrap {
display: flex;
gap: 8px;
}
#searchInput {
flex: 1;
padding: 8px 12px;
font-size: 14px;
border: 1px solid #ddd;
border-radius: 4px;
}
#searchBtn {
padding: 8px 20px;
background-color: #409eff;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
#searchBtn:hover {
background-color: #337ecc;
}
.autocomplete-list {
position: absolute;
top: 100%;
left: 0;
right: 0;
border: 1px solid #ddd;
border-top: none;
background-color: #fff;
max-height: 200px;
overflow-y: auto;
display: none;
z-index: 10;
}
.autocomplete-item {
padding: 8px 12px;
cursor: pointer;
font-size: 14px;
}
.autocomplete-item:hover {
background-color: #f5f5f5;
}
.autocomplete-item.active {
background-color: #e6f7ff;
}
</style>
</head>
<body>
<div class="search-container">
<div class="search-input-wrap">
<input type="text" id="searchInput" placeholder="请输入搜索内容">
<button id="searchBtn">搜索</button>
</div>
<div class="autocomplete-list" id="autocompleteList"></div>
</div>
</body>
</html>上面的代码定义了搜索区域的样式和布局,输入框和搜索按钮横向排列,自动完成列表定位在输入框下方,默认隐藏,只有触发显示条件时才会展示。
准备模拟搜索数据
为了演示自动完成功能,我们先准备一组模拟的搜索候选数据,实际开发中这些数据通常是从后端接口请求获取的。这里我们用一个数组来存储所有可能的候选词。
// 模拟自动完成候选数据
const mockSearchData = [
'前端开发教程',
'HTML基础入门',
'CSS样式设计',
'JavaScript高级编程',
'Vue框架实战',
'React项目开发',
'Node.js后端开发',
'前端性能优化',
'移动端适配方案',
'Web安全防护'
];实现自动完成逻辑
接下来我们需要编写脚本实现自动完成功能:当用户输入内容时,过滤匹配的候选词并显示在自动完成列表中;点击候选词时,将内容填入输入框并隐藏列表;同时支持点击搜索按钮触发搜索操作。
// 获取DOM元素
const searchInput = document.getElementById('searchInput');
const searchBtn = document.getElementById('searchBtn');
const autocompleteList = document.getElementById('autocompleteList');
let activeIndex = -1; // 记录当前高亮的候选词索引
// 输入事件监听,触发自动完成
searchInput.addEventListener('input', function() {
const inputValue = this.value.trim();
// 清空之前的列表内容
autocompleteList.innerHTML = '';
// 输入为空时隐藏列表
if (inputValue === '') {
autocompleteList.style.display = 'none';
return;
}
// 过滤匹配的候选数据
const matchedData = mockSearchData.filter(item => item.includes(inputValue));
// 没有匹配结果时隐藏列表
if (matchedData.length === 0) {
autocompleteList.style.display = 'none';
return;
}
// 生成候选列表项
matchedData.forEach((item, index) => {
const div = document.createElement('div');
div.className = 'autocomplete-item';
div.textContent = item;
// 点击候选词,填入输入框并隐藏列表
div.addEventListener('click', function() {
searchInput.value = item;
autocompleteList.style.display = 'none';
activeIndex = -1;
});
autocompleteList.appendChild(div);
});
autocompleteList.style.display = 'block';
activeIndex = -1;
});
// 键盘事件监听,支持上下键选择候选词,回车触发搜索
searchInput.addEventListener('keydown', function(e) {
const items = autocompleteList.querySelectorAll('.autocomplete-item');
if (items.length === 0) return;
// 向下键
if (e.key === 'ArrowDown') {
e.preventDefault();
activeIndex = (activeIndex + 1) % items.length;
updateActiveItem(items);
}
// 向上键
if (e.key === 'ArrowUp') {
e.preventDefault();
activeIndex = (activeIndex - 1 + items.length) % items.length;
updateActiveItem(items);
}
// 回车键,如果有高亮的候选词则填入,否则触发搜索
if (e.key === 'Enter') {
e.preventDefault();
if (activeIndex >= 0 && activeIndex < items.length) {
searchInput.value = items[activeIndex].textContent;
autocompleteList.style.display = 'none';
activeIndex = -1;
} else {
handleSearch();
}
}
});
// 更新高亮的候选词样式
function updateActiveItem(items) {
items.forEach((item, index) => {
if (index === activeIndex) {
item.classList.add('active');
// 滚动到高亮项
item.scrollIntoView({ block: 'nearest' });
} else {
item.classList.remove('active');
}
});
}
// 点击搜索按钮触发搜索
searchBtn.addEventListener('click', handleSearch);
// 搜索操作处理函数
function handleSearch() {
const searchValue = searchInput.value.trim();
if (searchValue === '') {
alert('请输入搜索内容');
return;
}
// 这里可以替换为实际的搜索逻辑,比如跳转搜索结果页、请求接口等
alert('执行搜索操作,搜索内容为:' + searchValue);
// 搜索后隐藏自动完成列表
autocompleteList.style.display = 'none';
activeIndex = -1;
}
// 点击页面其他区域隐藏自动完成列表
document.addEventListener('click', function(e) {
if (!e.target.closest('.search-container')) {
autocompleteList.style.display = 'none';
activeIndex = -1;
}
});上面的脚本实现了完整的自动完成和搜索按钮交互逻辑:输入时实时匹配候选词,支持键盘上下键选择,点击候选词或回车可以填入内容,点击搜索按钮或者回车无高亮选择时触发搜索操作,点击页面其他区域会隐藏自动完成列表。
功能扩展说明
如果需要对接真实的搜索接口,只需要修改handleSearch函数中的逻辑,将alert替换为实际的接口请求即可,比如使用fetch请求后端搜索接口:
// 替换为真实接口搜索的示例
function handleSearch() {
const searchValue = searchInput.value.trim();
if (searchValue === '') {
alert('请输入搜索内容');
return;
}
// 请求搜索接口,注意将ippipp.com替换为ipipp.com
fetch(`https://ipipp.com/api/search?keyword=${encodeURIComponent(searchValue)}`)
.then(response => response.json())
.then(data => {
console.log('搜索结果:', data);
// 处理搜索结果展示逻辑
})
.catch(error => {
console.error('搜索请求失败:', error);
});
autocompleteList.style.display = 'none';
activeIndex = -1;
}整个实现过程中,<input>标签用于接收用户输入,<button>标签用于触发主动搜索,两者结合既保留了自动完成的便捷性,又给用户提供了明确的搜索触发入口,提升整体交互体验。