原生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可能变的不在那么重要,原生一样 ...
随机推荐
- 【FLASK】使用ORM以及类似于Django更新新增字段
#!/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy.ext.declarative import declarative_base ...
- Python-类属性查询协议-__getattr__ __getattribute__
__getattr__ 查找不到类属性的时候调用 class BeiMenChuiXue: def __init__(self, name): self.name = name def __getat ...
- CS:APP配套实验 Data Lab
刚刚完成注册博客,想写一篇随笔,方便以后自己回顾.如果恰好也能帮助到你,是我的荣幸. 这次随笔是记载我的计算机系统(CS:APP,Computer Systems:A Programer's Pers ...
- 第三周:java面向对象部分总结(2)
<!--此处接上周--> 3.相关接口 对对象的排序,可以通过以下两种方法: 1.实现Comparable接口,重写compareTo方法: 2.Comparator<>比较器 ...
- three.js学习5_渲染器
THREE.WebGLRenderer WebGL Render 用WebGL渲染出你精心制作的场景 介绍 在之前的介绍中, 已经介绍过场景, 相机, 光源, 有了这些后, 就可以形成一个可观的三维展 ...
- Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- PyCharm 上安装 Package(以 pandas 为例)
一.使用 PyCharm 软件安装 pandas 包 1.打开 PyCharm 2.点击右上角 "Files" →"Settings..." 3.弹出" ...
- RHSA-2017:1931-中危: bash 安全和BUG修复更新(代码执行)
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...
- day56 Pyhton 前端Jquery08
前端 内容回顾: -BOM -jquery介绍 -jquery下载和引入方式 npm install jquery -jquery的选择器 -基本选择器 -通配符选择器 - id选择器 - 类选择器 ...
- JS关闭chorme页面
百度到的很多答案都失效了,这是收集一位博主的(https://www.jianshu.com/p/9dc2752194b8),目前可以使用. 代价是打开一个空白页面,能实现无提示关闭当前页面.不需要是 ...