cookie實作京東五星好評組件評分資料存盤
實作目標:
實作京東五星好評部分的組件,實作滑鼠經過星星時星星變紅色,星星上方出現對應星級的笑臉,同時在評價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);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/201665.html
標籤:其他
上一篇:JavaScript入門萌新須知
