原生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可能变的不在那么重要,原生一样 ...
随机推荐
- Apache Shiro 1.3.2入门
简介 Apache Shiro是一个功能强大且灵活的开放源代码安全框架,可以清楚地处理认证,授权,企业会话管理和加密.Apache Shiro的首要目标是易于使用和理解.有时候安全性可能非常复杂和痛苦 ...
- Python-集合 字典-set dict fronzenset
集合 set 1. 无序 2. 去重 3. 定义空集 set() numbers = {1, 3, 4, 5, 6, 5, 4, 4, 7, 8} print(numbers) print(numbe ...
- JSON.stringify 的使用
一.作用:这个函数的作用主要是为了序列化对象.就是把原来是对象的类型转换成字符串类型(json格式的String类型). 二.语法:JSON.stringify(value[, replacer][, ...
- 【题解】SP10570 【LONGCS - Longest Common Substring】
\(\color{Red}{Link}\) \(\text{Solution:}\) 还是\(\text{Suffix Tree.}\) 根据\(\color{Blue}{Link}\)我们可以得到一 ...
- Splay浅谈
Splay是众多平衡树之一,它的功能十分强大,但常数极大.在LCT和许多数据结构中都能用到. Splay的核心操作,就是rotate.为了使树不是一条链,而是平衡的,我们需要旋转来维护形态.理论很简单 ...
- Jmeter之连接数据库
1.下载mysql驱动文件 2.移动到Jmeter目录下的lib中 3.在配置文件中使用 jdbc:mysql://127.0.0.1:3306/fns_test_bak?useUnicode=tru ...
- 对ACE和ATL积分
下载source code - 39.66 KB 介绍 这篇文章展示了一种结合ACE和ATL的方法.它不打算作为功能演示,而是作为一个小型的"入门"解决方案,展示实现此目标的可行方 ...
- 用cmd下载tp5.0版本
1.首先进入phpstudy的www目录 composer create-project topthink/think=5.0.* pt5.0的名字 --prefer-dist $ composer ...
- LVS+keepalive
LVS+keepalive 什么是keepalive Keepalived是Linux下一个轻量级别的高可用解决方案.高可用(High Avalilability,HA),其实两种不同的含义:广义来讲 ...
- centos7 samba安装教程
samba的用途:有的时候,我们需要在centos7 的文件能共享给其他机器. rpm -qa|grep samba yum install -y samba setenforce 0 sed -i ...