原生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可能变的不在那么重要,原生一样 ...
随机推荐
- 俯瞰 Java 服务端开发
原文首发于 github ,欢迎 star . Java 服务端开发是一个非常宽广的领域,要概括其全貌,即使是几本书也讲不完,该文将会提到许多的技术及工具,但不会深入去讲解,旨在以一个俯瞰的视角去探寻 ...
- springboot整合Mangodb实现crud,高级查询,分页,排序,简单聚合
//linux安装mangodb教程:https://www.cnblogs.com/yangxiaohui227/p/11347832.html 1.引入maven 依赖 <dependenc ...
- WordPress用户角色权限
[转自:群燕小站(http://www.zqunyan.com):原文链接: http://www.zqunyan.com/158.html] WordPress默认的用户角色有5个:订阅者,投稿者, ...
- RabbitMQ小记(二)
1.RabbitMQ相关介绍 (1)RabbitMQ整体上是一个生产者和消费者模型,主要负责接收.存储.转发消息.RabbitMQ整体结构图如下: (2)生产者:发送消息的一方,生产者创建一条消息,发 ...
- Centos-对比文件差异-diff
diff 比较文件差异 相关选项 -c 显示全部内容,并标记不同之处 -b 忽略行尾空格,并认为字符串中一个或多个空格视为相同 -r 当比较双方都是目录时,会比较子目录中的文件 -s 当两个文件相同 ...
- 中心极限定理(为什么y服从高斯分布)
因为每一条数据都服从IID原则: 根据中心极限定理,当数据增加的时候,样本均值的分布慢慢变成正态分布 不管分布式什么分布,累加起来都是高斯分布 As sum increases, sum of non ...
- __declspec(dllexport)和__declspec(dllimport) (——declspec方法创建dll的方法已验证ok)
转载:https://www.cnblogs.com/chengbing2011/p/4084125.html __declspec(dllimport)和__declspec(dllexport)经 ...
- 099 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 03 编写并测试Student类
099 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 03 编写并测试Student类 本文知识点:编写并测试Subject类 说明: ...
- JVM内存布局(又叫Java运行时数据区)
JVM 堆中的数据是共享的,是占用内存最大的一块区域. 可以执行字节码的模块叫作执行引擎. 执行引擎在线程切换时怎么恢复?依靠的就是程序计数器. JVM 的内存划分与多线程是息息相关的.像我们程序中运 ...
- day25 Pyhton学习 约束和异常处理
一.类的约束 约束是对类的约束 有两种方法: 1.提取一个父类,在父类中给出一个方法,并且在方法中不给出任何代码,直接抛异常 class Base: def login(self): raise Ex ...