原生JS结合cookie实现商品评分组件
开发思路如下:
1.利用JS直接操作DOM的方式开发商品评分组件,主要实现功能有:显示评价评分的样式以及将用户操作后对应的数据返回到主页面
2.主页面引入商品评分组件的js文件并根据规定格式的数据,生成对应的组件元素并插入页面
3.主页面利用侦听事件接收组件抛发的数据并保存,每次有组件抛发事件都会覆盖上次抛发的数据,直到页面关闭,将最后一次抛发的数据保存到cookie中。
4.当再次打开主页面时,先判断cookie中是否有对应的数据,如果有提取cookie其中的数据,先根据页面数据生成对应的组件元素,再将cookie中数据传入对应组件元素中重新渲染,最后将元素插入主页面
注意点:因为当再次打开页面,用户可能不一定会修改所有的组件元素,这样组件抛出的数据就不完整,不会是所有元素的数据,当我们在保存数据的时候需要和上一次保存的数据进行比对,只覆盖和上一次保存数据不同的属性,保证数据的完整性。
主页面JS部分代码如下:
import Star from "./js/Star.js"; var data=["商品符合度","店家服务态度","快递配送速度","快递员服务","快递包装"]; var cookieStorage={}; // 初始化加载先拿到cookie,切割好数据之后,在初始化创建渲染完评分数据对象之后,再通过setData的方法修改数据 var hository=JSON.parse(document.cookie.split("=")[1]); data.forEach((item)=>{ var star=new Star(item); star.addEventListener("change",changeHandler); if(JSON.stringify(hository)!=="{}"){//判断cookie中是否有对应的数据 star.setData(hository[item]) } star.appendTo(".ShowStarList"); }) cookieStorage=hository; function changeHandler(e){ for(var prop in e.StarList){//因为当再次打开页面,用户可能不一定会修改所有的组件元素,这样抛出的数据就不完整不会是所有元素的数据 cookieStorage[prop]=e.StarList[prop]; } } //页面点击操作之后,将数据存放到cookieStorage中,当下一次再点击时将cookieStorage中的数据覆盖 // 直到页面被关闭时,触发下述事件,将cookieStorage+时间段的方式存储到cookie中 window.onbeforeunload=closeHandler; function closeHandler(){ var date=new Date(); date.setFullYear(2021); document.cookie="cookieStorage="+JSON.stringify(cookieStorage)+";expires="+date.toUTCString(); }
商品评分组件JS部分代码如下:
`
import Base from "./Base.js";
export default class Star extends Base{
static StarList = {};//用来存储数据选中的评分数据到时候返回页面
label;
starCon = [];
pos=-1
labelWrap;
starWrap;
face;
scoreWrap;
constructor(_label) {
// 第一次创建是用label生成的对象,后面都是用StarList去渲染对象
super();
this.label = _label;
this.elem.setAttribute("class", "StarCon");
this.createStarCon();
this.setStyle();
}
//创建评分组件的HTML结构
createStarCon() {
this.labelWrap = document.createElement("span");
this.labelWrap.textContent = this.label;
this.starWrap = document.createElement("div");
for (let i = 0; i < 5; i++){
let singleStar = document.createElement("div");
singleStar.setAttribute("class", "singleStar");
this.starWrap.appendChild(singleStar);
this.starCon.push(singleStar);
}
this.face = document.createElement("div");
this.starWrap.appendChild(this.face);
this.scoreWrap = document.createElement("span");
this.scoreWrap.textContent = "0分";
this.labelWrap.setAttribute("class", "label");
this.starWrap.setAttribute("class", "star");
this.face.setAttribute("class", "face");
this.scoreWrap.setAttribute("class", "score");
this.elem.appendChild(this.labelWrap);
this.elem.appendChild(this.starWrap);
this.elem.appendChild(this.scoreWrap);
this.starWrap.addEventListener("mouseover",e=>this.mouseHandler(e));
this.starWrap.addEventListener("click",e=>this.mouseHandler(e));
this.starWrap.addEventListener("mouseleave",e=>this.mouseHandler(e));
}
mouseHandler(e) {
// click和mouseover都要不停渲染星星样式,所以都要通过遍历识别鼠标当前指向的是哪个e.target,从而通过for循环渲染星星
// 其中点击事件和鼠标移动事件不同的地方在于
// 点击事件会记录下一个全局变量pos表示选中该数据,且会抛出事件传递包括同页面其他实例对象的数据给页面
// 鼠标移动事件则是利用相同原理除了渲染星星外,还要渲染分数和笑脸
switch (e.type) {
case "mouseover":
let index = this.starCon.indexOf(e.target);
if (index < 0) return;
this.changeScore(index + 1);
this.changeFace(index);
this.changeStar(index);
break;
case "click":
let index1 = this.starCon.indexOf(e.target);
if (index1 < 0) return;
this.pos = index1;
this.dispatch();
this.changeStar(index1);
break;
case "mouseleave":
this.changeStar(this.pos);
this.changeScore(this.pos + 1);
this.changeFace(-1);
break;
}
}
//根据分数改变星星样式
changeStar(n){
for(var i=0;i<this.starCon.length;i++){
if(i<=n || i<=this.pos){
this.starCon[i].style.backgroundPositionY="-16px";
}else{
this.starCon[i].style.backgroundPositionY="0px";
}
}
}
//根据分数改变分数样式
changeScore(n){
this.scoreWrap.textContent=n+"分";
if(n===0){
this.scoreWrap.style.color="#999";
}else{
this.scoreWrap.style.color="#e4393c";
}
}
//根据分数改变笑脸样式
changeFace(n){
if(n<0){
this.face.style.display="none";
return
}
var index=5-n-1
// 鼠标移动时,笑脸的div位置和其背景图的位置都要同时移动
// 鼠标离开或者点击之后,笑脸消失
this.face.style.display="block";
this.face.style.backgroundPositionX=-index*20+"px";
this.face.style.left=this.starCon[n].offsetLeft+"px";
}
//每次点击后抛发改变后的实例化组件元素群组的数据
dispatch() {
Star.StarList[this.label]=this.pos+1;
var evt=new Event("change");
evt.score=this.pos+1;
evt.label=this.label;
evt.StarList=Star.StarList;
this.dispatchEvent(evt);
}
//根据cookie传入的数据重新渲染组件元素
setData(historyScore) {
if (historyScore < 1) return;
this.pos = historyScore-1;
this.changeStar(historyScore-1);
this.changeScore(historyScore);
}
//设置实例化组件的样式
setStyle() {
Utils.addCSS(".label",{
float: "left",
height: "16px",
font: '12px / 150% tahoma, arial, "Microsoft YaHei", "Hiragino Sans GB", 宋体, sans-serif',
marginRight: "10px",
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
color: "rgb(102, 102, 102)",
});
Utils.addCSS(".star",{
float: "left",
height: "16px",
position: "relative",
marginTop: "1px",
});
Utils.addCSS(".singleStar",{
float: "left",
height: "16px",
width: "16px",
backgroundImage: "url(../img/commstar.png)",
backgroundPositionY: "0px",
});
Utils.addCSS(".face",{
height: "16px",
width: "16px",
backgroundImage: "url(../img/face-red.png)",
position:"absolute",
top:"-16px",
display: "none",
backgroundPositionX:"0px",
left:"0px",
});
Utils.addCSS(".score",{
position:"relative",
width:"30px",
height:"16px",
top:"-2px",
marginLeft: "10px",
font: '12px / 150% tahoma, arial, "Microsoft YaHei", "Hiragino Sans GB", 宋体, sans-serif',
textAlign:"right",
color:"#999",
});
}
}
`
原生JS结合cookie实现商品评分组件的更多相关文章
- 原生js实现一个侧滑删除取消组件(item slide)
组件,本质上是解决某个问题封装的类,在此记录原生js实现侧滑删除 先上效果图 实现思路 1. 确定渲染的数据结构 2. 思考划分布局,总的有两个主要的模块:内容区域和按钮区域 2.1 内容区域保持宽度 ...
- 原生JS 的cookie和jq的cookie,
COOKIE基础及应用:1.什么是COOKIE==>页面用来保存信息,比如:自动登录,记住用户名2.COOKIE的特性: --同一个网站中,所有的页面共享同一套cookie --数量,大小有 ...
- 原生js实现简洁的返回顶部组件
本文内容相当简单,所以没有发布到博客园首页,如果你不幸看到,那只能是我这篇文章的荣幸,谢谢你的大驾光临~(本博客返回顶部的功能就使用的是这个组件) 返回顶部组件是一种极其常见的网页功能,需求简单:页面 ...
- 原生js操作cookie
写cookie function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTim ...
- 原生js封装cookie获取、设置及删除
使用cookie(key,value,options) 参数key,value,options(可选) function cookie(key,value,options){ if(typeof va ...
- 原生js对cookie的增删改查
一.增 document.cookie = cname + "=" + cvalue + ";expires=" + expires + ";path ...
- 原生js登录创建cookie
原生js创建cookie,功能:点击登录按钮时,将用户名.密码存为cookie:页面再次加载时,自动读取cookie中的用户名.密码. <html><head><titl ...
- js里cookie操作
原生js操作cookie 创建和存储 cookie 在这个例子中我们要创建一个存储访问者名字的 cookie.当访问者首次访问网站时,他们会被要求填写姓名.名字会存储于 cookie 中.当访问者再次 ...
- 放弃jQuery,使用原生js吧!
转自:http://itakeo.com/blog/2015/07/28/nojq/ 随着IE6.7.8的逐渐淘汰,HTML5的兴起,以及侧重点放在了移动端,jQuery可能变的不在那么重要,原生一样 ...
随机推荐
- 最精美详尽的 HTTPS 原理图!
来源:r6a.cn/ffJk 作为一个有追求的程序员,了解行业发展趋势和扩充自己的计算机知识储备都是很有必要的,特别是一些计算机基础方面的内容,就比如本篇文章要讲的计算机网络方面的知识.本文将为大 ...
- Spring整合JDBC(连接池、JDBC模板、Dao配置到Spring容器、配置文件的优化)
1.Spring整合JDBC (1)导包(共12个): c3p0连接池.JDBC驱动(4个) Spring-jdbc.Spring-tx事务(2个) (2)JDBC模板对象(JDBCTemplate) ...
- Android作业0930
1.使用ListView和Adapter实现购物商城 Android 布局文件 <?xml version="1.0" encoding="utf-8"? ...
- mysql-5-aggregation
#2.分组函数 /* 分组函数/聚合函数:传入一组值,经过统计处理,得到一个输出值 sum, avg, max, min, count */ USE myemployees; #简单使用 SELECT ...
- 【题解】[CH弱省胡策R2]TATT
本蒟蒻第一道\(K-D-Tree\)维护\(dp\) Question 题目大意:求一条路径,使得其四个维度单调不降. 先排序消掉一维再说. 对于每一个点,初始的时候绝对长度是1啊.于是,先赋值一个1 ...
- 远程触发Jenkins的Pipeline任务
场景 虽然能配置提交代码时触发Jenkins任务,但有时并不需要每次提交代码都触发,而是仅在有需要时才执行. 除了在Jenkins页面上手动执行任务,还可以向Jenkins网站发起HTTP请求,触发指 ...
- CF724G 【Xor-matic Number of the Graph】
题目就不翻译了吧,应该写的很清楚了... 首先 \(,\) 不懂线性基的可以戳这里.知道了线性基\(,\) 但是从来没有写过线性基和图论相结合的\(,\) 可以戳这里. 好\(,\) 点完了这些前置技 ...
- 2018年10月份编程语言排行榜(来自TIOBE Index for October 2018)
TIOBE Index for October 2018 from:https://www.tiobe.com/tiobe-index// October Headline: Swift is kno ...
- RHSA-2017:2473-重要: 内核 安全和BUG修复更新(需要重启、存在EXP、本地提权)
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...
- RHSA-2017:1842-重要: 内核 安全和BUG修复更新(需要重启、存在EXP、本地提权、代码执行)
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...