JavaScript 五星好评组件实现与 Cookie 存储
作者:白露时间:2026-10-25 03:34:03浏览:628
本文介绍使用原生 JavaScript 实现五星好评组件的方法。通过继承 Component 基类构建 Star 组件,处理星星、笑脸及分数的交互逻辑。重点解决 DOM 元素创建顺序与定位问题,并在点击后触发 change 事件,将评分结果持久化存储至 Cookie 中,便于后续维护与数据保存。
五星好评组件实现与数据存储
本文展示了一个使用 JavaScript 实现五星好评功能的具体代码示例,供读者参考学习。
业务逻辑的核心在于预先构建所需的 DOM 标签与样式,并抽象出星星、分数、笑脸及点击行为的具体处理规则,以提升代码的可维护性。交互触发后,系统会抛出事件并记录名称、分数等关键信息,最终将这些数据保存至 Cookie 中。
开发过程中主要面临两个技术难点:一是 DOM 元素的创建顺序,需避免在元素未生成时执行 appendChild 导致错误;二是在绑定交互行为时,如何精准调整星星与笑脸的位置布局。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module">
import Star from "./js/Star.js";
let list=["商品符合度","店家服务态度","快递配送速度","快递员服务","快递包装"]
list.forEach(item => {
let star = new Star(item);
star.appendTo("body");
star.addEventListener("change",changeHandler);
});
function changeHandler(e){
var date=new Date();
date.setMonth(11);
setCookie(e.scoreList,date);
function setCookie(data,date){ //JSON形式存储到cookie中
var str=date===undefined ? "" : ";expires="+date.toUTCString();
for(var prop in data){
var value=data[prop];
if(typeof value==="object" && value!==null) value=JSON.stringify(value);
document.cookie=prop+"="+value+str;
}
}
}
</script>
</body>
</html>
export default class Component{ //创建warp 和 appendTo方法
elem;
constructor(){
this.elem=this.createElem();
}
createElem(){
if(this.elem) return this.elem;
let div=document.createElement("div");
return div;
}
appendTo(parent){
if(typeof parent==="string")parent=document.querySelector(parent);
parent.appendChild(this.elem);
}
}
import Component from "./Component.js";
export default class Star extends Component{
label="";
score;
face;
starCon;
static STAR_NUM=5;
starArr=[];
static StarScoreList=[];
pos=-1;
constructor(_label){
super();
this.label=_label;
Object.assign(this.elem.style,{
width:"auto",
height:"16px",
float:"left",
paddingBottom:"10px",
marginRight:"20px",
paddingTop:"16px",
})
Star.StarScoreList[_label]=0;
this.createLable(_label);
this.createStar();
this.createScore();
}
createLable(_label){
let labels=document.createElement("div");
labels.textContent=_label;
Object.assign(labels.style,{
float:"left",
height: "16px",
lineHeight: "16px",
marginRight: "10px",
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
font: '12px/150% tahoma,arial,Microsoft YaHei,Hiragino Sans GB,"\u5b8b\u4f53",sans-serif',
color: "#666"
});
this.elem.appendChild(labels);
}
createStar(){
this.starCon=document.createElement("div");
Object.assign(this.starCon.style,{
float:"left",
height:"16px",
position:"relative",
marginTop:"1px"
})
for(let i=0;i<Star.STAR_NUM;i++){
let star=document.createElement("div");
Object.assign(star.style,{
backgroundImage:"url(./img/commstar.png)",
width:"16px",
height:"16px",
float:"left",
})
this.starArr.push(star);
this.starCon.appendChild(star);
}
Object.assign(this.face.style,{
width:"16px",
height:"16px",
backgroundImage:"url(./img/face-red.png)",
position:"absolute",
top:"-16px",
display:"none"
});
this.starCon.appendChild(this.face);
this.elem.appendChild(this.starCon);
this.starCon.addEventListener("mouseover",e=>this.mouseHandler(e))
this.starCon.addEventListener("click",e=>this.mouseHandler(e))
this.starCon.addEventListener("mouseleave",e=>this.mouseHandler(e))
this.face=document.createElement("div");
}
createScore(){
this.score=document.createElement("span");
Object.assign(this.score.style,{
position:"relative",
width:"30px",
height:"16px",
top:"-2px",
marginLeft:"10px",
lineHeight:"16px",
textAlign:"right",
color:"#999",
font:"12px/150% tahoma,arial,Microsoft YaHei,Hiragino Sans GB,sans-serif",
});
this.score.textContent="0分";
this.starCon.appendChild(this.score);
}
mouseHandler(e){ //鼠标行为
let index=this.starArr.indexOf(e.target);
switch(e.type){
case "mouseover":
if(index<0) return;
this.changeFace(index);
this.changeScore(index+1);
this.changeStar(index+1);
break;
case "click":
this.pos=index;
this.dispatch();
break;
case "mouseleave":
this.changeStar(this.pos+1);
this.changeFace(this.pos);
this.changeScore(this.pos+1);
break;
default:
return;
}
}
changeStar(n){
for(let i=0;i<this.starArr.length;i++){
if(i<n){
this.starArr[i].style.backgroundPositionY="-16px";
}else{
this.starArr[i].style.backgroundPositionY="0px";
}
}
}
changeScore(n){
this.score.textContent=n+"分";
if(n===0){
this.score.style.color="#999";
}else{
this.score.style.color="#e4393c";
}
}
changeFace(n){
if(n<0){
this.face.style.display="none";
return;
}
let index=Star.STAR_NUM-n-1; //这里的笑脸因为图片的原因是反向的
this.face.style.display="block";
this.face.style.backgroundPositionX=-index*20+"px";
this.face.style.left=this.starArr[n].offsetLeft+"px";
}
changeScore(n){
this.score.textContent=n+"分";
if(n===0){
this.score.style.color="#999";
}else{
this.score.style.color="#e4393c";
}
}
dispatch(){
// console.log("aaa")
Star.StarScoreList[this.label]=this.pos+1;
var evt=new Event("change");
evt.score=this.pos+1;
evt.label=this.label;
evt.scoreList=Star.StarScoreList;
this.dispatchEvent(evt);
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
作者最新文章
sigma.js 怎么实现节点点击、拖拽与悬停提示交互
2026-11-05 15:03:27
Matter.js 与 PixiJS/Three.js 集成:分离物理计算与渲染
2026-11-05 13:43:48
主流JS弹幕库选型指南:Danmaku.js等库的功能与体积对比
2026-11-05 09:28:19
JavaScript点击事件监听与交互效果实例
2026-11-05 09:10:19
自定义JS颜色选择器UI样式与交互细节
2026-11-05 09:09:06
