如何利用js脚本制作星级评分系统

来源:AI智能体作者:石川澪头衔:网络博主
导读:本期聚焦于石川澪创作的《如何利用js脚本制作星级评分系统》,敬请观看详情。很多前端开发场景都需要用到星级评分功能,比如商品评价、内容打分模块等。本文将从基础原理出发,讲解如何利用原生js脚本实现星级评分系统,涵盖页面结构搭建、样式设计、交互逻辑编写全流程。我们会逐步拆解鼠标悬停高亮、点击固定评分、取消评分等核心功能,同时提供完整的可运行代码示例,即使是js基础薄弱的开发者也能跟着步骤完成开发,快速掌握星级评分功能的实现思路。

星级评分系统是前端界面中常见的交互组件,它的核心并不只是展示五颗星,而是通过一组明确的状态规则响应用户操作。用户将鼠标移动到某个评分项上时,界面需要预先展示该分值对应的效果;鼠标离开后,界面要回到已经确认的评分状态;当用户点击某个评分项时,当前分值被固定下来,并同步到提示文本中。只要把结构、样式和事件三个层面拆解清楚,就可以用原生JavaScript完成一个稳定、易维护的评分组件。

一、页面结构:让每个评分项都携带明确分值

在搭建结构时,需要先确定组件由哪几部分组成。一个评分容器负责包裹所有评分项,一个提示区域负责显示当前评分,若干个评分项则分别代表一分到五分。为了让脚本能够准确识别每个评分项对应的分值,可以在每个评分项上添加自定义属性,例如 data-value。相比把分值写在文本内容里,再通过字符串解析,自定义属性更清晰,也更利于后续维护。

为了使结构保持轻量,可以使用 <div> 作为容器,使用 <span> 作为评分项,并使用 <p> 显示评分文本。这里的 <span> 是普通HTML元素,不是函数调用。每个评分项默认显示中文“星”,并通过类名区分普通状态和高亮状态。这样即使不使用图片字体,也可以表达评分含义。

<div class="star-rating">
  <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>
  <p class="rating-text">当前评分:0</p>
</div>

这段结构的关键在于所有评分项都拥有相同的类名和不同的 data-value。脚本后续可以通过类名批量获取节点,再通过自定义属性读取分值。提示文本初始显示零分,代表用户尚未提交评分。这样的结构既简单,又能清楚表达评分组件的基本语义。

二、样式设计:用类名表达默认、预览与确认状态

样式层面要解决的是视觉反馈问题。默认状态下,评分项使用较浅的颜色,表示尚未激活;当某个评分项进入高亮状态时,颜色变为更醒目的暖色,表示当前预览或已确认的分值。为了让状态切换更自然,可以给颜色变化加入短暂的过渡效果。同时,将鼠标指针设置为手型,可以提示用户该区域可点击。

在具体实现中,推荐通过一个状态类名来控制高亮,例如 active。JavaScript只需要增加或移除这个类名,而不需要直接修改每个节点的内联样式。这样可以让样式规则集中在CSS中,脚本只负责状态切换,代码职责更清晰,也方便后期统一调整视觉风格。

.star-rating {
  font-size: 24px;
  color: #ccc;
  cursor: pointer;
}
.star {
  margin-right: 5px;
  transition: color 0.2s;
}
.star.active {
  color: #ffc107;
}
.rating-text {
  margin-top: 10px;
  font-size: 16px;
}

以上样式中,容器设置了统一字号和默认颜色,评分项之间保留少量间距,提示文本与评分项之间也保留了适当距离。由于高亮状态完全依赖 active 类名,后续无论悬停预览还是点击确认,都只需要操作同一个类名即可。这种写法减少了重复样式判断,也让组件状态更容易理解。

三、脚本逻辑:用事件驱动评分状态

JavaScript部分的核心是一个状态变量和三类事件。状态变量 currentRating 保存用户已经确认的评分,初始值为零。悬停事件只负责临时预览,不应该修改这个变量;点击事件才负责更新变量。这样可以避免预览状态和确认状态互相干扰,也能让组件行为更加稳定。

在获取节点时,可以使用 document.querySelectorAll 获取所有评分项,使用 document.querySelector 获取提示文本。为了避免重复编写高亮逻辑,可以抽取一个渲染函数,根据传入的分值遍历所有评分项。当评分项的分值小于或等于目标分值时,添加高亮类名;否则移除高亮类名。这样无论是悬停、离开还是点击,都可以复用同一套渲染逻辑。

// 获取所有评分项与提示文本
const stars = document.querySelectorAll('.star');
const ratingText = document.querySelector('.rating-text');

// 当前已确认的评分,0表示尚未评分
let currentRating = 0;

// 根据传入的分值更新评分项的高亮状态
function renderStars(value) {
  stars.forEach(item => {
    const itemValue = parseInt(item.dataset.value, 10);
    if (itemValue <= value) {
      item.classList.add('active');
    } else {
      item.classList.remove('active');
    }
  });
}

// 更新评分提示文本
function renderText(value) {
  ratingText.textContent = '当前评分:' + value;
}

// 为每个评分项绑定交互事件
stars.forEach(star => {
  // 鼠标悬停时预览当前分值效果
  star.addEventListener('mouseover', function() {
    const hoverValue = parseInt(this.dataset.value, 10);
    renderStars(hoverValue);
  });

  // 鼠标移出时恢复已确认的评分状态
  star.addEventListener('mouseout', function() {
    renderStars(currentRating);
  });

  // 点击时确认评分,再次点击同一分值可取消
  star.addEventListener('click', function() {
    const clickValue = parseInt(this.dataset.value, 10);

    if (clickValue === currentRating) {
      currentRating = 0;
    } else {
      currentRating = clickValue;
    }

    renderStars(currentRating);
    renderText(currentRating);
  });
});

在这段脚本中,mouseover 事件根据当前悬停的评分项计算预览分值,并调用渲染函数展示效果。mouseout 事件并不关心鼠标移到了哪里,而是统一恢复到已确认的评分状态。这样做可以让界面始终围绕唯一的状态源进行更新,避免因为鼠标移动路径不同而产生不一致的视觉结果。

click 事件先判断当前点击的分值是否等于已确认分值,如果相等则取消评分,如果不相等则确认新的评分。这个判断实现了再次点击取消评分的能力,也让组件更接近真实表单场景中的操作习惯。提示文本会随着状态变化同步更新,使用户能够明确知道当前选择的分值。

四、整合思路与实现要点

将结构、样式和脚本组合后,整个组件的运行流程就非常清晰。页面加载后,脚本首先获取评分项和提示文本;当鼠标悬停时,界面展示临时预览;当鼠标移出时,界面恢复确认状态;当点击发生时,状态变量被更新,提示文本和评分项高亮同步变化。这种通过状态驱动视图的方式,使组件行为可预测,也方便后续调整。

在维护层面,有几个要点值得注意。首先,评分项数量变化时,只需要修改结构中的节点和对应的 data-value,脚本依然可以自动获取全部节点。其次,渲染函数集中处理高亮逻辑,避免了多个事件中重复编写相似代码。再次,提示文本通过 textContent 更新,能够保持内容简洁,也避免不必要的HTML解析。

在实际使用时,还可以根据页面风格调整颜色、字号和间距,也可以把中文“星”替换成其他视觉元素。不过,无论视觉表现如何变化,核心思路都保持一致:结构承载分值,样式表达状态,脚本监听事件并维护唯一评分状态。掌握这一套方法后,面对类似的悬停预览与点击确认组件,也可以快速拆解并完成实现。

js星级评分系统前端交互事件监听DOM操作修改时间:2026-06-29 18:36:39

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。