如何使用vanilla Javascript构建一个搜索栏

150 阅读7分钟

用vanilla Javascript过滤机器

在这篇文章中,我们将使用vanilla Javascript构建一个搜索栏,对你的搜索输入进行实时过滤和响应。

目标

在文章结束时,我们应该有一个具有功能性搜索栏的应用程序,如下图所示。

Sample Page

前提条件

要跟上本教程,你应该知道。

  • HTML。
  • CSS。
  • Javascript。

这个项目是在Rep网站上使用html/css/js stack开发的。请自由使用它来跟读文章。

我们的代码将被分割成三个不同的文件。

  1. HTML file (index.html):这包含我们所有的HTML代码。
  2. CSS file (style.css):这包含我们所有的CSS代码。
  3. SCRIPT file (script.js):这包含了所有的Javascript代码。

HTML

下面的HTML代码包括默认的html boilerplate ,我们的cssJavascript 文件与之相连。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>workshop filter search bar</title>
  </head>
  <body>
    <main>
      <header>
        <h2>This is Filter Machine written in Vanilla Js</h2>
        <div class="form-area">
          <form>
            <input
              type="search"
              placeholder="Type Here to filter the List"
              autofocus
            />
          </form>
        </div>
      </header>

      <div class="content">
        <div class="card">
          <p>A</p>
        </div>
        <div class="card">
          <p>B</p>
        </div>
        <div class="card">
          <p>C</p>
        </div>
        <div class="card">
          <p>D</p>
        </div>
        <div class="card">
          <p>E</p>
        </div>
        <div class="card">
          <p>F</p>
        </div>
        <div class="card">
          <p>G</p>
        </div>
        <div class="card">
          <p>H</p>
        </div>
        <div class="card">
          <p>I</p>
        </div>
        <div class="card">
          <p>I</p>
        </div>
        <div class="card" id="not-found">
          <p>Not in the List</p>
        </div>
      </div>
    </main>
    <script src="script.js"></script>
  </body>
</html>

上面的代码包含。

  • head 标签包含titleCSS 文件的链接。
  • 在我们的浏览器上显示的title ,表明页面的标题。
  • CSS链接直接指向我们的CSS文件,并帮助传递CSS文件中要应用于HTML内容的一组规则。
  • main 标签包含我们HTML页面的主要内容。
  • header 标签包含我们应用程序的标题。
  • h2 标签描述了我们的应用程序与包含搜索栏的表单。
  • divs ,其类属性为card ,每个字母都是重复的。
  • script 链接,指向我们的Javascript代码,就在关闭的</body> 标签之前。

CSS

首先,我们清除默认的margin,paddingbox-sizing 样式。

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

我们这样做是为了防止在元素的宽度和高度上默认添加边距和衬垫;并将盒型设置为border-box,它控制页面上每个元素与盒型有关的行为活动。

然后,我们对主要的内容区域进行样式设计。

main {
  width: 100vw;
  display: flex;
  flex-direction: column;
  align-items: center;
}

我们将宽度设置为浏览设备的视图宽度。然后我们使用Flexbox来实现响应式布局。

然后,我们设计标题。

header {
  width: 100%;
  height: 200px;
  background: darkslategray;
  border-radius: 0 0 100% 100%;
  padding: 50px;
  margin: 0 0 20px;
  color: white;
  font-family: "Trebuchet MS", "Lucida Sans Unicode", "Lucida Grande",
    "Lucida Sans", Arial, sans-serif;
  text-align: center;
}

我们设置宽度和高度,并使用background 属性设置背景颜色;background 属性可以有多个选项,例如:图像、颜色等。如果你愿意,你可以使用图像、任何其他图案,甚至是background-color 属性,这将做同样的事情。

现在,让我们装饰一下搜索栏的输入元素。

input {
  width: 70%;
  height: 50px;
  margin-top: 10px;
  outline: none;
  border: none;
  border-radius: 5px;
  font-size: 25px;
  padding-left: 20px;
}

我们将宽度设置为标题宽度的70%。我们添加一个边距,使其远离上方的(<h2>) 标签。我们使用border-radius 属性添加圆角。

然后,让我们来设计卡片的样式。

.card {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background-color: darkslategray;
  margin: 10px 0;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-size: 56px;
  font-family: monospace;
}

这些是包含英文字母的圆形卡片。我们设置border-radius: 50% ,使卡片变成圆形。其他属性与之前的模式相同。

然后,我们为错误卡设置样式。

.card:last-child {
  font-size: 30px;
  text-align: center;
  display: none;
}

:last-child 是一个CSS 伪类选择器,有助于选择包含在父元素中的最后一个子元素。当没有任何东西符合我们用户的搜索时,我们将显示这个卡片。这个实现将在javascript代码中完成。

使CSS具有响应性

开发一个可以通过手机和平板电脑访问的基于网络的应用程序很重要,因为移动设备无处不在。

有很多方法可以做到这一点;我们将使用media query 来实现响应性。

@media screen and (min-width: 768px) {
  header {
    height: 500px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    font-size: 30px;
  }
  input {
    height: 80px;
  }
}

我们将只控制我们应用程序的重要部分。在用户的屏幕大于768px ,标题将自动增加高度,搜索栏的高度也被增加。

另一个重要的属性是flex属性flex-direction ,我们将其设置为column ,使标题中包含的flex项目垂直显示。

Javascript代码

const input = document.querySelector("input");
const notFound = document.getElementById("not-found");

const filterFunction = () => {
  const cards = document.querySelectorAll(".card");
  cards.forEach((item) => {
    let whatToSearch = item.querySelector("p");
    if (
      whatToSearch.innerHTML.toUpperCase().indexOf(input.value.toUpperCase()) >
      -1
    ) {
      item.style.display = "";
    } else {
      item.style.display = "none";

      //  Not found logic

      notFound.style.display = "flex";
    }
  });
};
input.addEventListener("keyup", filterFunction);

以上是所有需要的Javascript代码。在下面的步骤中,我将解释这些代码的作用。

  • 第1行
const input = document.querySelector("input");

我们创建一个名为input 的变量。这个变量持有我们在HTML中创建的搜索栏的内容。querySelector 方法返回一个带有标签输入的每个HTML元素的列表。这里,我们只有一个。

以后,可以通过对input 变量使用Javascript的.value 方法来获得用户输入的内容。

  • 第3-4行
const filterFunction = () => {

我们使用ES6(ECMAScript 2015)语法创建一个新的箭头函数,filterFunction 。在该函数中,我们创建了另一个变量,用来保存每个card div。filterFunction 函数将包含所有的逻辑,以按照我们的意愿过滤页面上的一切。

const cards = document.querySelectorAll(".card");

我们使用querySelector ,就像之前解释的那样;每个具有card 类属性的元素都将作为数组中的一个项目被返回。

  • 第5行
cards.forEach((item) => {

然后,我们使用forEach 方法循环浏览返回的数组。

  • 第6行
let whatToSearch = item.querySelector("p");

在每张卡片里面,都有一个<p> 标签,用来存放字母。第5行使用querySelectorforEach 方法返回的项上创建一个变量来存放每个<p> 标签。

  • 第7-8行
if (whatToSearch.innerHTML.toUpperCase().indexOf(input.value.toUpperCase()) >-1)

然后我们使用一个if 语句来检查我们的搜索输入是否与我们正在搜索的div中的任何文本相匹配。

whatToSearch.innerHTML 返回 变量里面的字母,也就是 标签里面的字母。whatToSearch <p>

我们使用toUpperCase() ,将其转换为大写字母。然后我们使用indexOf ,检查用户的输入值是否在whatToSearch 的数值内找到。如果返回值大于-1 ,意味着搜索值与某物相匹配,如果不大于-1 ,则搜索值不在列表中。

  • 第9行
item.style.display = "";

这在项目上设置了一个CSS属性display ,默认为display 属性或CSS文件中的属性。

  • 第10行
item.style.display = "none";

如果类型字符不匹配,应该把display 设置为none ,也就是说,什么都不应该显示。

  • 第12-13行
notFound.style.display = "flex";

我们使用getElementById 方法在line 2 ,创建一个变量来保存最后一个div。这将返回传入的ID 的元素。CSSdisplay 属性被设置为flex,因为它在CSS文件中被设置为无。

  • 最后一行
input.addEventListener("keyup", filterFunction);

我们在输入端设置了一个keyup 事件监听器,当用户从键盘上松开手时,该监听器就会做出反应,并调用第3行中创建的函数。

总结

下面是我们刚刚建立的东西,是不是很神奇?

Demo

你刚刚构建的东西可以在各种现实生活中的项目中实现,并且可以通过以下方式进行改进。

  1. 可以通过添加更多的样式来修改搜索栏,使其更加突出,给人以更好的感觉。
  2. 在一个购物车的应用中,用户需要过滤出产品来获得他们的选择。这个应用程序可以被整合,以提供访问。
  3. 创意是这个应用程序的极限,因为它可以在任何需要过滤元素的应用程序上实施。