如何:使用 JavaScript 构建一个简单的搜索栏
大家好!
今天,我们将讲解如何使用 JavaScript 构建一个功能齐全但非常简单的搜索栏。这个小项目还会用到 CSS 和 HTML。
💭💭💭💭💭💭💭💭💭💭💭
让我们看看我们的目标:
现在我们已经清楚地了解了我们需要实现的目标...让我们开始吧!
创建基础文件
请记住:这是一个简单的项目。您可以根据需要添加和完善它。但就今天的需求而言,我们只需要三个文件:
- index.js
- 索引.html
- 样式.css
我们有一个(1)JavaScript 文件,它将保存我们的事件监听器、函数、变量声明+赋值以及我们的基本数据。
我们有一个(1)HTML 文件,它将保存我们的 DOM 元素并以可见的格式将我们的代码描绘到网页上。
我们有一个(1)CSS 文件,我们将使用它来设置 HTML 元素的样式并添加一些天赋和创造力。
您可以直接在代码编辑器中创建这些文件(通过右键单击并选择“新建文件”或使用新建文件按钮)或在终端中创建:
touch index.html
touch index.js
touch style.css
构建 HTML 基础知识
我通常利用 HTML5 的标准模式来开始;它看起来像这样:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Search Bar</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="index.js"></script>
</body>
</html>
在标题标签中,您可以随意命名您的项目。这不一定在浏览器页面上可见,但会作为浏览器上的标签显示。
<title>Search Bar</title>
首先要添加(首先,我的意思是马上添加!)的两件重要的事情是必要的link和script 标签。在开始构建 HTML 文件时,养成在 style.css 文件中添加 link 标签,并在 index.js 文件中添加 script 标签的习惯。
<head>
<link rel="stylesheet" href="style.css">
</head>
样式表应该放在 HTML 文件的 head 标签部分。此标签允许你在 CSS 文件中编写的任何样式在浏览器中可见地显示。
JavaScript 文件的 script 标签应该放在 body 标签中。通常将其放在底部。将 HTML 文件与任何 JS 文件连接起来非常重要。JS 文件将引用 HTML 中的 DOM 元素。
<body>
<script src="index.js"></script>
</body>
现在,我们需要在 HTML 主体中嵌套一些元素。我们肯定需要:
- 带有输入字段的表单元素
- “清除”按钮用于清除我们的结果
- 一个无序列表元素来保存我们的结果
以下是一个例子:
<body>
<div class="form-container">
<form class="form">
<input id="search" type="text" class="input" placeholder="search..."/>
<button id="clear" class="clear-results">clear</button>
</form>
</div>
<div class="results-container>
<ul class="results-list" id="list">
</ul>
</div>
<script src="index.js"></script>
</body>
为每个元素提供一个“类”名和/或“ID”。确保类名或 ID 名称能够反映元素的功能或提供的功能。
从外到内,我创建了一个名为“form-container”的 div 元素;这是 JavaScript 中的常规标准。我们希望将具有特定角色的不同部分嵌套在各自的容器中。因此,我们的表单容器包含表单及其相邻的按钮。然后,我们创建了另一个名为“results-container”的 div,它将用于保存结果。
在表单容器中,我创建了一个表单元素,用于存放后续的表单元素。我创建了一个输入标签,其类型为“text”,允许用户在输入表单中输入内容。我还提供了类名、ID 和占位符。然后,我创建了一个“submit”按钮,其类型也为“submit”,并且该按钮也拥有一个类名。按钮标签之间的文本将在浏览器中显示为“search”。“clear”按钮也采用同样的方法。
因此,我们的 HTML 文件已设置好:让我们继续我们的 JavaScript 文件。
创建简单数据
由于我们没有引用 API,因为这是一个简单的项目,我们将创建一些简单的数据,作为搜索结果呈现到页面上。请进入你的 index.js 文件。
我喜欢使用 JavaScript 嵌套数组创建数据。今天的例子,我们的数据是人名。所以我们的数组名为“people”。
const people = []
每个数组项都将是一个对象 --- 这意味着每个数组项都将具有一个属性和值。
const people = [
{ name: 'adri'},
{ name: 'becky'},
{ name: 'chris'},
{ name: 'dillon'},
{ name: 'evan'},
{ name: 'frank'},
{ name: 'georgette'},
{ name: 'hugh'},
{ name: 'igor'},
{ name: 'jacoby'},
{ name: 'kristina'},
{ name: 'lemony'},
{ name: 'matilda'},
{ name: 'nile'},
{ name: 'ophelia'},
{ name: 'patrick'},
{ name: 'quincy'},
{ name: 'roslyn'},
{ name: 'solene'},
{ name: 'timothy'},
{ name: 'uff'},
{ name: 'violet'},
{ name: 'wyatt'},
{ name: 'x'},
{ name: 'yadri'},
{ name: 'zack'},
]
这是我们简单的数据!您可以随意创建食物、颜色、电视节目等任何您想要的数组!
建立事件监听器
我们需要设置两个事件监听器。一个事件监听器等待某个事件发生(“点击”、“按键”、“输入”),然后触发相应的操作。在本例中,我们需要在用户在输入表单中输入信息以及用户点击清除按钮时触发相应的操作。在 JavaScript 中,事件监听器的语法如下所示:
whateverElement.addEventListener("event type", () => {
}
因此,为了让我们的输入表单附加一个事件监听器,我将使用 querySelector 通过其类名检索按钮并将其设置为常量(以便以后可以使用)。
const searchInput = document.querySelector('.input')
我现在要将事件监听器附加到我们声明和分配的常量上:
searchInput.addEventListener("input", (e) => {
// inside, we will need to achieve a few things:
// 1. declare and assign the value of the event's target to a variable AKA whatever is typed in the search bar
let value = e.target.value
// 2. check: if input exists and if input is larger than 0
if (value && value.trim().length > 0){
// 3. redefine 'value' to exclude white space and change input to all lowercase
value = value.trim().toLowerCase()
// 4. return the results only if the value of the search is included in the person's name
// we need to write code (a function for filtering through our data to include the search input value)
} else {
// 5. return nothing
// input is invalid -- show an error message or show no results
}
}
让我们为清除按钮创建一个基础:
const clearButton = document.getElementById('clear')
clearButton.addEventListener("click", () => {
// 1. write a function that removes any previous results from the page
})
在页面上显示结果
为了展示我们的结果,我们必须最终遍历我们的简单数据,如果任何数据与输入值匹配,则将数据附加到页面(可见)。
让我们创建一个函数,首先将结果附加到网页。
// creating and declaring a function called "setList"
// setList takes in a param of "results"
function setList(results){
for (const person of results){
// creating a li element for each result item
const resultItem = document.createElement('li')
// adding a class to each item of the results
resultItem.classList.add('result-item')
// grabbing the name of the current point of the loop and adding the name as the list item's text
const text = document.createTextNode(person.name)
// appending the text to the result item
resultItem.appendChild(text)
// appending the result item to the list
list.appendChild(resultItem)
}
}
现在,我们已经写了如何将结果附加到页面;我们需要集中精力弄清楚应该将什么内容附加到页面。
回到事件监听器,我们之前在 #4 处停了下来。
我们将调用“setList()”并传入 people 数组,但不是整个数组。我们将过滤 people 数组,只使用 name 值包含搜索输入值的 people 项。
searchInput.addEventListener("input", (e) => {
let value = e.target.value
if (value && value.trim().length > 0){
value = value.trim().toLowerCase()
//returning only the results of setList if the value of the search is included in the person's name
setList(people.filter(person => {
return person.name.includes(value)
}))
让我们测试一下,如果我们在搜索栏中输入“be”,“becky”应该出现在搜索栏下方的页面上。
你看到了什么?
清除页面结果
要从页面中删除结果,我们需要调用“列表”元素并删除每个子元素,因为现在我们的结果项是“列表”的子元素。
一种简单、快捷的方法是删除父元素的第一个子元素,直到没有子元素为止……我们可以使用“while”循环来做到这一点。
** While 循环:当条件仍然为真时,执行所描述的操作。**
function clearList(){
// looping through each child of the search results list and remove each child
while (list.firstChild){
list.removeChild(list.firstChild)
}
}
我们可以在事件监听器中引用这个函数 clearList()——
searchInput.addEventListener("input", (e) => {
// inside, we will need to achieve a few things:
// 1. declare and assign the value of the event's target to a variable AKA whatever is typed in the search bar
let value = e.target.value
// 2. check: if input exists and if input is larger than 0
if (value && value.trim().length > 0){
// 3. redefine 'value' to exclude white space and change input to all lowercase
value = value.trim().toLowerCase()
// 4. return the results only if the value of the search is included in the person's name
// we need to write code (a function for filtering through our data to include the search input value)
} else {
// 5. return nothing
clearList()
}
}
clearButton.addEventListener("click", () => {
clearList()
})
未显示结果
好吧,我们必须问自己,如果输入值没有匹配结果怎么办?没有结果?我们需要准确地告诉用户!
让我们创建一个名为“noResults()”的函数。此函数会在页面上显示错误信息,也就是显示结果的位置。
function noResults(){
// create an element for the error; a list item ("li")
const error = document.createElement('li')
// adding a class name of "error-message" to our error element
error.classList.add('error-message')
// creating text for our element
const text = document.createTextNode('No results found. Sorry!')
// appending the text to our element
error.appendChild(text)
// appending the error to our list element
list.appendChild(error)
}
我们可以在 setList() 函数中使用此函数:
function setList(results){
clearList()
for (const person of results){
const resultItem = document.createElement('li')
resultItem.classList.add('result-item')
const text = document.createTextNode(person.name)
resultItem.appendChild(text)
list.appendChild(resultItem)
}
if (results.length === 0 ){
noResults()
}
}
测试我们的代码
现在,我们已经编写了精美的 JavaScript 文件和 HTML 文件,并加载了事件监听器、变量声明和函数,我们可以测试我们的代码。
转到您的浏览器...在您的终端中,输入:
open index.html
这是我所看到的...我添加了一个标题并做了一些轻微的样式...
非常感谢你阅读并和我一起编写代码。希望你也能从这个迷你 JavaScript 项目中学到很多东西。
请留下评论、问题或建议。让我们一起继续学习。💭💭💭💭💭💭💭💭💭💭💭💭💭💭💭