原生JS实现可自定义星级评分系统
本文介绍如何使用原生JavaScript实现一个可自定义星星数量和显示信息的星级评分系统。内容涵盖CSS绘制三角形、元素定位、事件代理、性能优化及正则表达式应用,并提供完整代码示例与调用方法,帮助开发者掌握相关前端技术。
星级评分系统介绍
本文分享一个实用的前端实例:可自定义星星数量及显示信息的星级评分系统。
使用方法与参数说明
调用方式简单:使用默认配置时,直接执行 sufuStar.star(),系统将生成5颗星星及默认提示信息。若需自定义,可传入参数,例如 sufuStar.star(10, msg),其中第一个参数指定星星数量为10,第二个参数 msg 为自定义显示信息数组。需注意,msg 数组的元素个数必须与星星数量保持一致,格式可参考默认值设定。
通过独立实现此类实例,能够有效提升对各项知识点的熟练度,并有助于发现自身知识盲区。一旦识别出薄弱环节,应立即查阅API文档进行针对性补充学习。
该实例的开发耗时较长,作者花费了整整一天时间完成编码与调试。
涉及的核心技术点
本实例涉及以下核心技术点: 1. 利用CSS的 border 属性绘制三角形,并通过 ::before 伪元素将其插入到其他元素中; 2. 掌握CSS元素定位技巧; 3. 理解并应用事件代理机制; 4. 关注代码性能优化策略; 5. 运用 String 对象的 match 方法及正则表达式进行字符串处理; 6. 实现事件注册与处理,并包含兼容IE浏览器的写法; 7. 利用逻辑或运算符 '||' 为变量设置默认值; 8. 代码简化:将重复使用的逻辑抽取为独立函数。
下方提供了带有详细注释的完整代码。若遇到不理解的部分,建议查阅相关文档。基于当前技术水平,代码已尽可能完善,欢迎有经验的前辈提出改进建议。
完整代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
#star{
position: absolute;
left: 0;
right: 0;
top: 30px;
bottom: 0;
margin: auto;
width: 80%;
font-size: 12px;
}
#star-div{
margin:5px;
font-size: 0;
}
#star-div a{
display: inline-block;
width: 21px;
height: 21px;
background: url(http://files.cnblogs.com/files/susufufu/star0.gif) no-repeat;
}
#star-div .on{
background: url(http://files.cnblogs.com/files/susufufu/star1.gif) no-repeat;
}
#star-info{
position: absolute;
top: 55px;
left: -30px;
display: none;
width: 155px;
height: 50px;
padding: 2px;
line-height: 17px;
border-radius: 8px;
background-color: gold;
z-index: 5;
}
#star-info:before{
content: '';
border-bottom: 10px solid gold;
border-left: 10px solid rgba(0,0,0,0);
border-right: 10px solid rgba(0,0,0,0);
position: absolute;
left: 35px;
top: -10px;
}
#star-span{line-height: 14px}
#star-info strong,#star-span strong{
color: red;
}
</style>
<script>
window.onload = function(){
var sufuStar = function (){
//工具函数
function gbyId(id){return document.getElementById(id);}
function addEvent(elem,type,func){ //兼容IE
if(elem.addEventListener){
elem.addEventListener(type,func,false)
}else if(elem.attachEvent){
elem.attachEvent('on'+type,func)
}
}
function getIndex(event) { //兼容IE
var e = event || window.event;
var t = e.target || e.srcElement;
if (t.tagName.toLowerCase() === 'a') {
return parseInt(t.innerHTML);
}
}
function showInfo(index,msg){
var info = gbyId('star-info');
info.style.display = 'block';
info.style.left = index*21-51+'px';
info.innerHTML = "<strong> "+index+'分 '+msg[index-1].match(/(.+)\|/)[1]+'<br />'+'</strong>'+msg[index-1].match(/\|(.+)/)[1];
}
function appenStar(elem,nums){
var frag = document.createDocumentFragment(); //为了提高性能,因使用DocumentFragment一次性append,这样页面只重新渲染一次
for(var i = 0;i<nums;i++){
var a =document.createElement('a');
a.innerHTML = i+1;
a.href = "javascript:;"; //阻止浏览器的点击链接的默认行为
frag.appendChild(a);
}
elem.appendChild(frag);
}
//主体函数
function star(num,myMsg){
var n = num||5; //当num有值则取其值,无值则取默认值5;
var clickStar=curentStar=0; //clickStar保存点击状态
var msg = myMsg||[
"很不满意|差得太离谱,与卖家描述的严重不符,非常不满",
"不满意|部分有破损,与卖家描述的不符,不满意",
"一般|质量一般,没有卖家描述的那么好",
"满意|质量不错,与卖家描述的基本一致,还是挺满意的",
"非常满意|质量非常好,与卖家描述的完全一致,非常满意"
];
var starContainer = gbyId('star-div');
appenStar(starContainer,n);
addEvent(starContainer,'mouseover',over); //采用事件代理模式(通过<a>标签的父元素starContainer来代理事件)
addEvent(starContainer,'mouseout',out);
addEvent(starContainer,'click',click);
function over(event){
if(getIndex(event)){ //若getIndex(event)取不到值,说明当前触发事件的目标不是<a>标签
var index = getIndex(event);
change(index);
showInfo(index,msg);
}
}
function out(event){
change(); //将评分设为已点击状态clickStar
gbyId('star-info').style.display = 'none'
}
function click(event) {
if (getIndex(event)) {
var index = getIndex(event);
clickStar = index; //保存点击状态
gbyId('star-info').style.display = 'none';
gbyId('star-span').innerHTML = "<strong>" + index + '分 ' + msg[index - 1].match(/(.+)\|/)[1] + '</strong>'+'<br />'+ msg[index - 1].match(/\|(.+)/)[1];
}
}
function change(index){
curentStar = index||clickStar;
for(var i=0;i<n;i++){
starContainer.children[i].className = i<curentStar ? 'on' : ''
}
}
}
return {
star:star
}
}(); //这里的()表示函数立即执行,这样变量sufuStar才能调用匿名函数的返回值star
//调用执行: sufuStar.star(num,myMsg),参数可为空,参数num,myMsg将设为默认值
sufuStar.star();
}
</script>
</head>
<body>
<div id="star">
<span>点击星星打分:</span>
<div id="star-div">
</div>
<span id="star-span"></span>
<p id="star-info">
</p>
</div>
</body>
</html>
以上为本文的全部内容,希望这对大家的学习有所帮助,同时也欢迎大家继续支持本站。
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
D3.js 与 ECharts 选型对比:灵活性 vs 开发效率
2026-11-05 09:45:01
