Vanilla JavaScript进行页面内过滤搜索
如果你有一个包含大量信息的页面,让用户搜索他们可能要找的东西是一个好主意。我说的不是搜索数据库,甚至不是搜索JSON数据--我说的是在单个渲染的网页上搜索文本。用户已经可以使用内置的浏览器搜索,但我们可以通过提供我们自己的搜索功能来增强这一功能,在页面上进行过滤,使匹配结果更容易找到和阅读。
下面是我们要建立的一个现场演示。
CodePen嵌入回退
我在我的真实项目中也使用了这种技术:https://freestuff.dev/。
认识一下JavaScript!
好吧,你可能已经知道了JavaScript。JavaScript将处理这个旅程中的所有交互性。它将会...
找到所有我们要搜索的内容。
观察用户在搜索输入中输入的内容。
过滤可搜索元素的
innerText
。测试文本是否包括搜索词(
.includes()
是这里的重头戏!),以及切换(父)元素的可见性,取决于它们是否包括搜索词。
好了,我们有了我们的要求!让我们开始工作。让我们开始工作吧。
基本标记
让我们假设我们有一个FAQ页面。每个问题都是一个 "卡片",有一个标题和内容。
<h1>FAQ Section</h1> <div class="cards"> <h3>Who are we</h3> <p>It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularized </p> </div> <div class="cards"> <h3>What we do</h3> <p>It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularized </p> </div> <div class="cards"> <h3>Why work here</h3> <p>It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularized</p> </div> <div class="cards"> <h3>Learn more</h3> <p>Want to learn more about us?</p> </div>复制代码
想象一下,这个页面上有很多问题。
为了为交互性做好准备,我们将有这一行CSS。这给了我们一个类,我们可以根据搜索的情况,在我们进入JavaScript的时候添加/删除。
.is-hidden { display: none; }复制代码
让我们添加一个搜索输入,当它被交互时,会有一个事件触发。
<label for="searchbox">Search</label> <input type="search" oninput="liveSearch()" id="searchbox" >复制代码
JavaScript的基线
这里是做其他事情的JavaScript!
function liveSearch() { // Locate the card elements let cards = document.querySelectorAll('.cards') // Locate the search input let search_query = document.getElementById("searchbox").value; // Loop through the cards for (var i = 0; i < cards.length; i++) { // If the text is within the card... if(cards[i].innerText.toLowerCase() // ...and the text matches the search query... .includes(search_query.toLowerCase())) { // ...remove the `.is-hidden` class. cards[i].classList.remove("is-hidden"); } else { // Otherwise, add the class. cards[i].classList.add("is-hidden"); } } }复制代码
你也许可以逐行查看并推理出它在做什么。它找到所有的卡片和输入并保存对它们的引用。当一个搜索事件发生时,它循环浏览所有的卡片,确定文本是否在卡片内。如果卡片中的文本与搜索查询相匹配,.is-hidden
类就会被移除以显示卡片;如果不匹配,该类就在那里,卡片就会保持隐藏。
这里又是演示的链接。
添加一个延迟
为了确保我们的JavaScript不会运行_太多_(意味着它会拖慢页面),我们将在等待 "X "秒后才运行我们的liveSearch
函数。
<!-- Delete on Input event on this input --> <label for="searchbox">Search</label> <input type="search" id="searchbox">复制代码
// A little delay let typingTimer; let typeInterval = 500; // Half a second let searchInput = document.getElementById('searchbox'); searchInput.addEventListener('keyup', () => { clearTimeout(typingTimer); typingTimer = setTimeout(liveSearch, typeInterval); });复制代码
模糊搜索怎么办?
比方说,你想通过用户不可见的文本进行搜索。这个想法有点像模糊搜索,相关的关键词返回的结果与完全匹配的结果相同。这有助于扩大可能 "匹配 "搜索查询的卡片数量。
有两种方法可以做到这一点。第一种是使用一个隐藏的元素,比如span,它包含关键词。
<div class="cards"> <h3>Who are we</h3> <p>It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularized</p> <!-- Put any keywords here --> <span class="is-hidden">secret</span> </div>复制代码
然后我们需要更新我们的liveSearch函数。我们将使用.inner
Text,而不是使用.textContent
来包括隐藏元素。请看更多关于innerText和textContent之间区别的细节。
for (var i = 0; i < cards.length; i++) { if(cards[i].textContent.toLowerCase() .includes(search_query.toLowerCase())) { cards[i].classList.remove("is-hidden"); } else { cards[i].classList.add("is-hidden"); } }复制代码
试着在搜索框中输入 "secret",它应该会显示这张卡片,尽管 "secret "并没有显示在页面上。
CodePen嵌入回退
第二种方法是通过一个属性进行搜索。比方说,我们有一个图片库。我们可以把关键词直接放在图片的alt
属性上。尝试在下一个演示中输入 "小猫 "或 "人类"。这些查询是与图片alt
文本中包含的内容相匹配的。
CodePen嵌入回退
为了使其发挥作用,我们需要将innerText
改为getAttribute('alt')
,因为我们想通过alt
属性来查看页面上实际可见的内容。
for (var i = 0; i < cards.length; i++) { if(cards[i].getAttribute('alt').toLowerCase() .includes(search_query.toLowerCase())) { cards[i].classList.remove("is-hidden"); } else { cards[i].classList.add("is-hidden"); } }复制代码
根据你的需要,你可以把你的关键词放在另一个属性中,或者是一个自定义的属性。
注意事项
同样,这不是一个通过查询数据库或其他数据源来工作的搜索技术。只有当你在该页面的DOM中拥有所有可搜索的内容,并且已经呈现出来时,它才能工作。
所以,是的,就是这样。只是要记住的东西。
收尾工作
显然,我非常喜欢这种技术,足以在生产网站上使用它。但你还可以如何使用这样的东西呢?正如我们所看到的,常见问题页面是一个明显的候选者,但任何需要过滤任何类型内容的情况都适合这种东西。甚至一个图片库也可以,使用隐藏的输入技巧来搜索图片的alt
标签内容。
不管是什么情况,我希望你觉得这很有帮助。我很惊讶,我们可以用几行虚无缥缈的JavaScript得到一个相当强大的搜索解决方案。
作者:前端小工
链接:https://juejin.cn/post/7023648636831694861