每个人都有自己喜欢的框架,而且大多数开发人员并不羞于分享这些意见。我向你保证,现在有两个开发人员正在争论他们最喜欢的框架。就个人而言,自从引入 JQuery 以来,我一直在使用 JavaScript 框架。我使用 Knockout.js、Angular 1+、React(从 v15 之前开始)为客户编写了应用程序,并使用 Stencil 和 Vue 制作了一些小型学习应用程序。
所有这些框架带来的一大好处是它们易于组合。制作可在整个应用程序中重用的组件的能力对开发时间、代码可重用性和可测试性有很大帮助。您不必使用框架来获得这些好处。JavaScript 内置了它们,你只需要知道在哪里看。此外,学习如何在 vanilla JavaScript 中构建组件将帮助您了解如何在您最喜欢的框架中制作这些组件。
在这篇文章中,我将向您展示如何使用原生 JavaScript、CSS 和 HTML 构建一个简单的星级评分组件。我将使用VS Code和http-server来构建和提供一组静态文件。您需要安装Node.js和npm才能运行http-server
。
为 JavaScript 组件定义所需的行为
当我在任何框架(或没有框架)中构建组件时,我喜欢首先弄清楚我需要组件在内部处理的所有事情。在这种情况下,我正在构建一个星级组件,所以它肯定需要显示星星。
- 星形组件将具有所有星形的默认颜色。
- 如果组件在渲染时有评分值,它应该改变所有星星的颜色,直到并包括表示评分的星星。
- 当用户将鼠标悬停在组件上时,组件中的每个星,直到并包括他们悬停在的星,都应该改变颜色。
- 如果用户点击一个星,组件的当前评级应该更新以反映他们点击的星评级。
- 如果他们在没有选择评级的情况下将鼠标移开,则该组件应将星星的颜色设置回以反映最后选择的评级。
考虑到您的 JavaScript 组件的这些要求,让我们深入研究!
构建 JavaScript 组件应用程序的外壳
首先在您想要提供应用程序的地方创建一个文件夹。当您http-server
在目录中运行时,它将该文件夹用作 Web 服务器。创建目录后,在 VS Code 中打开它并添加一个名为index.html
. 这将是您的 Web 应用程序。里面index.html
。该文件将包含两个星级 HTML 元素以及一些基本样式和一个脚本标记。完整内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
.star-rater .star {
font-size: 5rem;
color: gray;
}
</style>
<title>Rater</title>
</head>
<body>
<h2>Star Rating</h2>
<div id="rater-1" class="star-rater" data-rating="3" role="rater">
<span class="star" data-value="1">★</span>
<span class="star" data-value="2">★</span>
<span class="star" data-value="3">★</span>
<span class="star" data-value="4">★</span>
<span class="star" data-value="5">★</span>
</div>
<div id="rater-2" class="star-rater" data-rating="2" role="rater">
<span class="star" data-value="1">★</span>
<span class="star" data-value="2">★</span>
<span class="star" data-value="3">★</span>
<span class="star" data-value="4">★</span>
<span class="star" data-value="5">★</span>
</div>
<script type="module" src="js/main.js"></script>
</body>
</html>
你会注意到我已经role="rater"
为每个元素添加了 。这将是您告诉主 JavaScript 文件将Rater
组件的功能附加到此元素的方式。
现在创建一个名为的文件夹js
来存放您的 vanilla JavaScript 组件代码,然后在该新文件夹中创建两个名为rater.js
and的文件。main.js
上面的那个script
标签将main.js
文件作为一种module
类型引入。对于支持 JavaScript 模块语法的浏览器,这将允许您使用ES2015 中引入的import
and语句。export
在rater.js
文件中添加代码以导出评估者的功能:
export function Rater(ratingElement) {
const stars = ratingElement.querySelectorAll('.star');
}
第一个功能也在这里。接收一个 HTML 元素并使用Rater
一个类查询它的所有元素,star
并将它们放入stars
数组中。
要完成外壳程序,请将代码添加到main.js
文件中,以查找所有具有角色的 HTML 元素rater
并将它们传递给Rater
组件。
import { Rater } from './rater.js';
document.addEventListener('DOMContentLoaded', function() {
const raters = document.querySelectorAll('[role=rater]');
raters.forEach(rater => {
new Rater(rater);
});
});
现在您应该能够通过提供文件夹来启动应用程序。从文件所在的文件夹在index.html
控制台运行:
http-server .
它会告诉你它正在http://localhost:8080上运行,你会看到两个带有灰色星号的评级组件,但它们还没有做任何事情。
构建 JavaScript 组件的功能
首先添加基于评级数字突出显示的功能。在rater.js
文件中,添加一个函数来突出显示每个星,包括某个评级:
const highlightRating = (rating) => {
stars.forEach(star => {
star.style.color =
rating >= star.getAttribute('data-value') ? 'yellow' : 'gray';
});
}
现在,您需要在组件呈现时为其设置初始突出显示。每个评估者 HTML 元素都有一个data-value
属性。这将用于保存组件的当前额定值。由于您将在组件加载时以及用户将鼠标从组件上移开后使用它,因此请调用函数resetRating()
. 在函数的正上方添加以下highlightRating()
函数:
const resetRating = ev => {
const currentRating = ratingElement.getAttribute('data-rating');
highlightRating(currentRating);
};
然后在highlightRating()
函数下方调用它,以便您可以为初始加载设置突出显示。
resetRating();
现在,当您重新加载浏览器时,您应该会看到每个评分者都突出显示为其适当的默认评分。在这种情况下,三个和两个。
下一步是处理悬停动作,以便在用户悬停在评级组件上时突出显示。您首先需要为每颗星连接一个偶数。由于您已经将组件中的所有星星放在一个数组中,只需循环它们并将事件侦听器挂在它们上面。将以下代码添加到组件函数的底部:
stars.forEach(star => {
star.addEventListener('mouseover', ratingHover);
});
现在,您需要侦听器的事件处理程序。这甚至只会让用户鼠标悬停在星号上并调用该highlightRating()
函数。在函数的正上方resetRating()
添加:
const ratingHover = ev => {
const currentHover = ev.currentTarget.getAttribute('data-value');
highlightRating(currentHover);
};
当用户将鼠标从评分组件上移开时,您还希望组件重置回上次选择的评分(在本例中为默认评分)。将以下代码行添加到组件函数的底部:
ratingElement.addEventListener('mouseout', resetRating);
现在,如果您刷新页面,您应该会看到悬停发生,当您将鼠标移开时,它应该重置突出显示。
现在只剩下一件事要做,那就是将点击事件连接到星星,并data-rating
在用户点击星星时更新组件。
要连接 click 事件,请更新该stars.forEach()
行,使其如下所示:
stars.forEach(star => {
star.addEventListener('click', setRating);
star.addEventListener('mouseover', ratingHover);
});
现在您有了一个单击和悬停的侦听器,添加setRating()
事件处理程序以在用户单击组件函数第一行下方的星时设置评分:
const setRating = ev => {
ratingElement.setAttribute(
'data-rating',
ev.currentTarget.getAttribute('data-value')
);
};
现在,当您刷新浏览器时,您应该能够将鼠标悬停在评级组件上并看到突出显示的情况。然后,当您单击星号时,它应该更新data-rating
评级组件元素的值。您可以在浏览器的开发者工具中查看。
让 JavaScript 组件更上一层楼
我使这个组件保持简单,以说明如何制作该组件并使其可被import
语句重用。既然您知道如何在 vanilla JavaScript 中构建和使用组件,那么您可以让这个组件做更多事情!
您可以让组件“绘制”星星并max-stars
在元素上设置一个属性来告诉组件要绘制多少颗星星。您可以使用Font Awesome 之类的东西来显示除星星之外的其他内容。您甚至可以让 Rater 组件调用另一个组件,该组件将用户选择的评分发送回 API 以保存到数据库中。但骷髅在那里。
rater.js
export function Rater(ratingElement) {
const stars = ratingElement.querySelectorAll('.star');
const resetRating = ev => {
const currentRating = ratingElement.getAttribute('data-rating');
highlightRating(currentRating);
};
const highlightRating = (rating) => {
stars.forEach(star => {
star.style.color =
rating >= star.getAttribute('data-value') ? 'yellow' : 'gray';
});
}
const ratingHover = ev => {
const currentHover = ev.currentTarget.getAttribute('data-value');
highlightRating(currentHover);
};
resetRating();
stars.forEach(star => {
star.addEventListener('mouseover', ratingHover);
});
ratingElement.addEventListener('mouseout', resetRating);
const setRating = ev => {
ratingElement.setAttribute(
'data-rating',
ev.currentTarget.getAttribute('data-value')
);
};
stars.forEach(star => {
star.addEventListener('click', setRating);
star.addEventListener('mouseover', ratingHover);
});
}