Cookieは、Jingdongの5つ星の賞賛コンポーネントのスコアデータの保存を実現します
目標の達成:
ジンドンの5つ星の賞賛部分の構成要素を実現するには、マウスが星の上を通過すると星が赤くなり、星に対応する笑顔が星の上に表示されることを認識します。同時に、n個の星を評価した後、スコアがnポイントとして表示されます。Cookieキャッシュを使用して、ユーザーにページを更新させます。または、ページを再度開くと、ラストクリックの星評価が自動的に表示され、再評価できます。ブラウザのデータキャッシュをクリアすると、評価されていない最初のページが表示されます。
htmlコード部分
<!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=["商品符合度","店家服务态度","快递配送速度","快递员服务","快递包装"]
for(var i=0;i<list.length;i++){
let star=new Star(list[i]);
star.appendTo("body");
}
</script>
</body>
</html>
jsコード部分
import Component from "./Component.js";
export default class Star extends Component {
label = "";
starCon;
face;
score;
pos = -1;
starArr = [];
static STAR_NUM = 5;
constructor(_label) {
super();
this.label = _label;
console.log(this.label)
Object.assign(this.elem.style, {
width: "auto",
float: "left",
height: "16px",
paddingBottom: "10px",
marginRight: "20px",
paddingTop: "16px",
});
this.createLabel(_label);//创建本文
this.createStar();//创建星星
this.createScore();//创建分数
this.list = this.getCookie();//获取缓存
//需要写判断条件,当第一次打开该页面或上次有未评价选项再次打开页面时,没有cookie缓存,获取的缓存是个空对象,如果不写判断条件,该选项的分数会为undefined分
if (this.list[this.label]) {
this.changeStar(this.list[_label] - 1);
this.changeScore(this.list[_label]);
} else {
//当所有选项都有评价,再次打开浏览器先执行获取缓存,改变性星星和分数,使打开的页面显示与上次退出时一致
this.changeStar(-1);
this.changeScore(0);
}
}
// 获取缓存
getCookie() {
if (document.cookie.length === 0) return {};
return document.cookie.split(";").reduce((value, item) => {
var arr = item.split("=");
var v = arr[1].trim();
try {
v = JSON.parse(v);
} catch (e) {}
value[arr[0].trim()] = v;
return value;
}, {});
}
// 创建文本
createLabel(_label) {
let labels = document.createElement("span");
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, {
width: "16px",
height: "16px",
float: "left",
backgroundImage: "url(./img/commstar.png)",
});
this.starArr.push(star);
this.starCon.appendChild(star);
}
//添加鼠标事件,鼠标经过星星时变色,点击星星时确定有几个星星颜色变色,移开鼠标时保持星星颜色为红色,同时修改显示的分数
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");
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);
}
// 创建分数
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,"\u5b8b\u4f53",sans-serif',
});
this.score.textContent = "0分";
this.elem.appendChild(this.score);
}
// 鼠标点击更改星星分数和笑脸
mouseHandler(e) {
switch (e.type) {
case "click":
case "mouseover":
let index = this.starArr.indexOf(e.target);
if (index < 0) return;
if (e.type === "click") {
this.pos = index;
this.setCookie();
} else {
this.changeScore(index + 1);
this.changeFace(index);
}
this.changeStar(index);
break;
case "mouseleave":
this.changeStar(this.pos);
this.changeScore(this.pos + 1);
this.changeFace(-1);
break;
}
}
// 改变星星
changeStar(n) {
for (var i = 0; i < this.starArr.length; i++) {
if (i <= n || i <= this.pos) {
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;
}
var 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";
}
// 添加缓存
//每次点击每一个评分项都将该项重新写入缓存
setCookie() {
var date = new Date();
date.setFullYear(2025);
document.cookie =
this.label + "=" + (this.pos + 1) + ";expires=" + date.toUTCString();
}
}
効果を達成する
初期状態:ページを初めて開いたときに効果が表示されます
マウスが通り過ぎるとき:星の色を変更し、対応する星のスマイリーフェイスとスコアを表示します
クリックして終了:スターが確認され、スコアが確認され、スマイリーフェイスが表示されなくなります。
ページを再度開くか、ブラウザを再起動します:表示効果は、マウスクリック後の左状態と同じです。ブラウザキャッシュをクリアして開くと、ページを初めて開いたときと同じ表示効果になります。
ページを更新してブラウザを再起動した
後の効果の表示:ブラウザのキャッシュをクリアした後の効果の表示:
上記のコードはスローイベントを追加しません。追加後、対応するスコア項目のスコアをイベントスローの形でスローできます。具体的な実装方法は以下のとおりです。
//在鼠标点击事件中添加dispatch()函数,将每一个评分项的评分以evt的属性的形式抛发出去
static StarScoreList = {};//用来保存每个选项的分数,用来抛发
dispatch(){
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);
}