
本教程详细指导如何使用原生javascript构建一个高效的搜索过滤器,并集成“无匹配项”提示功能。文章将涵盖html结构、css样式优化(强调`display: none`的优势),以及核心javascript逻辑,包括事件监听、元素过滤和根据搜索结果动态显示/隐藏提示信息。通过具体代码示例和最佳实践,帮助开发者提升用户体验。
在现代网页应用中,搜索过滤功能是提升用户体验的关键一环。当用户输入搜索词却没有找到任何匹配项时,一个清晰的“无匹配项”提示能有效避免用户困惑。本教程将详细介绍如何使用原生JavaScript实现一个带有此类提示的搜索过滤器。
首先,我们需要定义页面的基本HTML结构,包括搜索输入框、待过滤的卡片列表,以及用于显示“无匹配项”信息的段落。
<section id="seccion-diez" class="section">
<h2 data-dark>搜索过滤器</h2>
<!-- 搜索输入框,用于用户输入搜索词 -->
<input type="search" name="busqueda" placeholder="搜索..." class="card-filter">
<!-- 无匹配项提示信息,初始状态为隐藏 -->
<p class="hidden" id="mensaje">未找到匹配结果</p>
<!-- 待过滤的卡片容器 -->
<article class="contenedor-cards">
<!-- 示例卡片项 -->
<figure class="card">
@@##@@
<figcaption>自然</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>随机</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>科技</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>人物</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>动物</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>建筑</figcaption>
</figure>
</article>
</section>关键点:
为了实现元素的隐藏和显示,我们定义一个 .hidden 类。这里,我们推荐使用 display: none; 而非 visibility: hidden;。
.hidden {
display: none; /* 元素将从文档流中完全移除,不占据任何空间 */
opacity: 0; /* 配合 display: none 使用,虽然不影响布局,但可用于平滑过渡(如果结合JS移除display:none) */
order: 1; /* 弹性盒或网格布局中的排序属性,这里作为示例保留 */
}注意事项:display: none 与 visibility: hidden 的区别
在本教程的搜索过滤场景中,我们希望隐藏的卡片不占用任何空间,因此 display: none; 是更合适的选择。
JavaScript代码将负责监听搜索框的输入事件,根据输入内容过滤卡片,并根据过滤结果动态显示或隐藏“无匹配项”提示。
const d = document; // 简化 document 引用
/**
* 实现搜索过滤功能,并动态显示“无匹配项”提示。
* @param {string} inputSelector - 搜索输入框的CSS选择器。
* @param {string} cardSelector - 待过滤卡片的CSS选择器。
*/
function filtroBusqueda(inputSelector, cardSelector) {
d.addEventListener("keyup", (e) => {
// 检查事件是否来源于指定的搜索输入框,如果不是则提前返回,避免不必要的处理
if (!e.target.matches(inputSelector)) return;
// 如果按下的是Escape键,清空搜索框内容
if (e.key === "Escape") e.target.value = "";
// 获取所有待过滤的卡片元素
const cards = d.querySelectorAll(cardSelector);
const searchTerm = e.target.value.toLowerCase(); // 获取搜索词并转为小写
// 遍历所有卡片,根据搜索词进行显示或隐藏
cards.forEach((elemento) => {
// 检查卡片文本内容是否包含搜索词
if (elemento.textContent.toLowerCase().includes(searchTerm)) {
elemento.classList.remove("hidden"); // 包含则显示
} else {
elemento.classList.add("hidden"); // 不包含则隐藏
}
});
// 过滤出当前可见的卡片
// 使用 Array.from 或扩展运算符将 NodeList 转换为数组,以便使用 filter 方法
const visibleCards = Array.from(cards).filter(
(elemento) => !elemento.classList.contains("hidden")
);
// 根据可见卡片的数量来显示或隐藏“无匹配项”提示
const messageElement = d.querySelector("#mensaje");
if (visibleCards.length > 0) {
messageElement.classList.add("hidden"); // 有可见卡片,隐藏提示
} else {
messageElement.classList.remove("hidden"); // 没有可见卡片,显示提示
}
});
}
// 当DOM内容完全加载后,初始化搜索过滤器
d.addEventListener("DOMContentLoaded", () => {
filtroBusqueda(".card-filter", ".card");
});代码解析:
将上述HTML、CSS和JavaScript整合,即可实现一个功能完整的搜索过滤器。
index.html
<!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>
/* 基础样式,可根据需要调整 */
body { font-family: sans-serif; margin: 20px; }
.contenedor-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-top: 20px;
}
.card {
border: 1px solid #eee;
border-radius: 8px;
overflow: hidden;
text-align: center;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.card img {
width: 100%;
height: 150px;
object-fit: cover;
}
.card figcaption {
padding: 10px;
font-weight: bold;
}
input[type="search"] {
width: 100%;
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
#mensaje {
padding: 10px;
background-color: #ffe0b2;
color: #e65100;
border: 1px solid #ff9800;
border-radius: 4px;
text-align: center;
margin-bottom: 15px;
}
/* 隐藏元素的样式 */
.hidden {
display: none;
opacity: 0;
/* order: 1; 仅在flex或grid布局中生效,这里作为示例保留 */
}
</style>
</head>
<body>
<section id="seccion-diez" class="section">
<h2 data-dark>搜索过滤器</h2>
<input type="search" name="busqueda" placeholder="搜索..." class="card-filter">
<p class="hidden" id="mensaje">未找到匹配结果</p>
<article class="contenedor-cards">
<figure class="card">
@@##@@
<figcaption>自然</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>随机</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>科技</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>人物</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>动物</figcaption>
</figure>
<figure class="card">
@@##@@
<figcaption>建筑</figcaption>
</figure>
</article>
</section>
<script>
const d = document;
function filtroBusqueda(inputSelector, cardSelector) {
d.addEventListener("keyup", (e) => {
if (!e.target.matches(inputSelector)) return;
if (e.key === "Escape") e.target.value = "";
const cards = d.querySelectorAll(cardSelector);
const searchTerm = e.target.value.toLowerCase();
cards.forEach((elemento) => {
if (elemento.textContent.toLowerCase().includes(searchTerm)) {
elemento.classList.remove("hidden");
} else {
elemento.classList.add("hidden");
}
});
const visibleCards = Array.from(cards).filter(
(elemento) => !elemento.classList.contains("hidden")
);
const messageElement = d.querySelector("#mensaje");
if (visibleCards.length > 0) {
messageElement.classList.add("hidden");
} else {
messageElement.classList.remove("hidden");
}
});
}
d.addEventListener("DOMContentLoaded", () => {
filtroBusqueda(".card-filter", ".card");
});
</script>
</body>
</html>通过本教程,我们学习了如何使用原生JavaScript构建一个功能完善的搜索过滤器,并成功集成了“无匹配项”提示功能。这不仅提升了用户体验,还通过最佳实践(如 display: none 的使用、早期返回语句)优化了代码结构和性能。掌握这些技术将有助于您在前端开发中创建更具交互性和用户友好的界面。
以上就是构建原生JS搜索过滤器:添加“无匹配项”提示的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号