【JS 实战案例】实现一个简单的星级评分组件(交互版)
本文手把手实现一个实用的 JS 星级评分组件,支持半星评分、鼠标悬浮预览、点击确认评分、文本反馈等核心功能,适配 PC 和移动端。代码精简可复用,重点拆解鼠标位置计算、视觉分层高亮、事件组合交互等核心知识点,无冗余内容,贴合 CSDN 高分行文逻辑,助力前端零基础新手快速掌握这个高频实用的交互组件开发技巧。
·
🎯 案例核心效果
- 页面展示 5 星评分控件,鼠标悬浮时实时高亮对应星级,点击可确认评分;
- 支持半星评分(精准到 0.5 星),满足更细致的评分需求;
- 选中评分后给出文字反馈(如 “非常满意”“一般”),交互体验更友好;
- 样式简约美观,支持自定义星级颜色、大小,适配 PC 和移动端;
- 代码精简可复用,核心逻辑封装成函数,便于集成到表单、商品评价等场景。

📌 实现思路(极简清晰)
分 3 步落地,逻辑简单易上手,零基础也能快速掌握:
- HTML:搭建评分容器,包含星级元素和反馈文本区域,结构极简;
- CSS:实现星级样式、悬浮 / 选中状态高亮,半星效果通过背景渐变实现;
- JS:监听鼠标悬浮 / 点击 / 离开事件→计算高亮星级→更新样式和反馈文本→保存最终评分。
🚀 完整源码(可直接复制运行)
html
预览
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JS 星级评分组件 | 实战案例</title>
<style>
/* 全局重置(精简规范) */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Microsoft YaHei", sans-serif;
}
/* 页面布局:居中显示 */
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 20px;
background-color: #f5f5f5;
}
/* 标题样式 */
.title {
font-size: 24px;
color: #333;
margin-bottom: 30px;
text-align: center;
}
/* 评分容器 */
.rating-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
width: 100%;
max-width: 400px;
}
/* 星级容器:核心评分区域 */
.stars-wrapper {
position: relative;
display: flex;
font-size: 40px;
color: #e4e4e4; /* 未选中星级颜色 */
cursor: pointer;
}
/* 高亮星级层:通过宽度控制高亮范围 */
.stars-highlight {
position: absolute;
top: 0;
left: 0;
height: 100%;
overflow: hidden;
color: #ffd700; /* 选中星级颜色(金色) */
pointer-events: none; /* 禁止触发事件,避免遮挡底层 */
}
/* 反馈文本 */
.feedback-text {
font-size: 18px;
color: #666;
height: 24px;
text-align: center;
}
/* 最终评分展示 */
.result-text {
font-size: 16px;
color: #409eff;
margin-top: 10px;
}
/* 移动端适配 */
@media (max-width: 500px) {
.title {
font-size: 20px;
}
.stars-wrapper {
font-size: 32px;
}
.feedback-text {
font-size: 16px;
}
}
</style>
</head>
<body>
<h1 class="title">星级评分组件(支持半星)</h1>
<div class="rating-container">
<!-- 星级容器 -->
<div class="stars-wrapper" id="starsWrapper">
<!-- 高亮层:动态调整宽度实现星级高亮 -->
<div class="stars-highlight" id="starsHighlight">★★★★★</div>
<!-- 底层星级:用于鼠标交互 -->
<div class="stars-base">★★★★★</div>
</div>
<!-- 反馈文本 -->
<div class="feedback-text" id="feedbackText">请进行评分</div>
<!-- 最终评分 -->
<div class="result-text">最终评分:<span id="finalRating">0</span> 星</div>
</div>
<script>
// 1. 获取DOM元素
const starsWrapper = document.getElementById('starsWrapper');
const starsHighlight = document.getElementById('starsHighlight');
const feedbackText = document.getElementById('feedbackText');
const finalRating = document.getElementById('finalRating');
// 核心配置
const starCount = 5; // 总星级
let selectedRating = 0; // 最终选中的评分
// 评分对应的文本反馈
const feedbackMap = {
0: '请进行评分',
0.5: '极不满意',
1: '非常不满意',
1.5: '不满意',
2: '不太满意',
2.5: '一般',
3: '还不错',
3.5: '比较满意',
4: '满意',
4.5: '非常满意',
5: '极致满意'
};
// 2. 计算鼠标位置对应的星级(核心逻辑)
function calculateRating(e) {
// 获取星级容器的位置和宽度
const rect = starsWrapper.getBoundingClientRect();
// 计算鼠标在容器内的相对位置(x轴)
const x = e.clientX - rect.left;
// 计算当前星级(精准到0.5星)
let rating = (x / rect.width) * starCount;
// 四舍五入到最近的0.5星
rating = Math.round(rating * 2) / 2;
// 限制星级范围
rating = Math.max(0, Math.min(starCount, rating));
return rating;
}
// 3. 更新星级高亮和反馈文本
function updateRating(rating) {
// 调整高亮层宽度,实现星级高亮
starsHighlight.style.width = `${(rating / starCount) * 100}%`;
// 更新反馈文本
feedbackText.textContent = feedbackMap[rating] || feedbackMap[0];
}
// 4. 绑定鼠标悬浮事件:实时预览评分
starsWrapper.addEventListener('mousemove', (e) => {
const rating = calculateRating(e);
updateRating(rating);
});
// 5. 绑定鼠标离开事件:恢复选中的评分
starsWrapper.addEventListener('mouseleave', () => {
updateRating(selectedRating);
});
// 6. 绑定点击事件:确认评分
starsWrapper.addEventListener('click', (e) => {
selectedRating = calculateRating(e);
updateRating(selectedRating);
// 更新最终评分展示
finalRating.textContent = selectedRating;
});
// 初始化:默认显示0星
updateRating(selectedRating);
</script>
</body>
</html>
📖 核心代码拆解(重点突出,易懂好记)
1. HTML 结构(极简规整)
核心分为 2 部分,功能边界清晰:
stars-wrapper:星级容器,包含stars-highlight(高亮层)和stars-base(底层星级),通过两层叠加实现高亮效果;feedback-text/result-text:反馈文本和最终评分展示区域,提升交互反馈体验。
2. CSS 样式(简约美观,交互友好)
重点关注 3 个核心样式:
- 双层星级:底层显示灰色未选中星级,高亮层通过宽度控制金色星级的显示范围,实现星级高亮;
- 指针事件禁用:给高亮层添加
pointer-events: none,避免遮挡底层的鼠标交互; - 响应式适配:移动端缩小星级和文本尺寸,保证显示效果一致。
3. JS 逻辑(核心中的核心,分步拆解)
✅ 星级计算:
- 通过
getBoundingClientRect()获取容器位置,计算鼠标相对位置; - 将鼠标位置转换为星级,四舍五入到 0.5 星,满足半星评分需求;
- 限制星级范围在 0-5 之间,避免超出边界;
✅ 交互事件:
mousemove:鼠标悬浮时实时计算并更新星级高亮和反馈文本;mouseleave:鼠标离开时恢复到已选中的评分,避免预览状态残留;click:点击时保存最终评分,更新展示区域;
✅ 反馈映射:
- 通过
feedbackMap对象将评分与文本反馈绑定,提升用户感知; - 初始化时默认显示 0 星反馈,保证页面加载状态完整。
💡 新手常见踩坑点(精准避坑,少走弯路)
- 高亮层遮挡鼠标事件? → 未给
stars-highlight添加pointer-events: none,导致鼠标无法触发底层交互,需禁用高亮层的事件响应; - 半星评分不精准? → 未对计算出的星级做四舍五入到 0.5 星的处理,需添加
Math.round(rating * 2) / 2; - 移动端评分错位? → 未使用
getBoundingClientRect()获取实时位置,而是用固定宽度,需基于当前容器位置计算鼠标坐标; - 鼠标离开后高亮不恢复? → 未在
mouseleave事件中恢复选中的评分,需调用updateRating(selectedRating); - 星级超出 5 星 / 低于 0 星? → 未限制星级范围,需添加
Math.max(0, Math.min(starCount, rating))。
🔧 扩展思路(落地性强,新手可练)
- 只读模式:添加配置项,支持设置只读评分(仅展示,不可交互);
- 自定义配置:支持自定义星级数量、颜色、大小,适配不同设计风格;
- 分数转换:添加评分与分数的转换(如 5 星 = 10 分,3.5 星 = 7 分),适配表单提交;
- 动画效果:添加星级高亮的过渡动画,提升交互流畅度;
- 批量评分:扩展为多组评分组件(如商品的 “质量”“服务”“物流” 多维度评分);
- 表单集成:添加隐藏输入框,选中评分后自动赋值,便于表单提交到后端。
🎯 核心知识点总结(凝练精准,实战导向)
- 鼠标位置计算:掌握
getBoundingClientRect()获取元素位置,实现精准的鼠标交互; - 视觉分层:通过双层元素叠加 + 宽度控制,实现动态高亮效果;
- 事件组合:结合
mousemove/mouseleave/click实现完整的交互闭环; - 数据映射:通过对象映射实现评分与文本的关联,提升代码可维护性;
- 边界处理:对计算结果做范围限制,保证程序健壮性;
- 响应式交互:适配不同设备的鼠标 / 触摸交互,保证体验一致。
📢 互动留言
跟着案例实操一遍,轻松实现带半星的星级评分组件!这个功能在商品评价、表单反馈、问卷调查等场景中高频使用,复制代码就能直接复用。如果遇到半星不精准、高亮层遮挡事件等问题,评论区留言,我会第一时间解答;你还想给评分组件添加哪些扩展(比如只读模式、自定义颜色),也可以留言告诉我~
更多推荐
所有评论(0)