开发思路如下:

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实现商品评分组件的更多相关文章

  1. 原生js实现一个侧滑删除取消组件(item slide)

    组件,本质上是解决某个问题封装的类,在此记录原生js实现侧滑删除 先上效果图 实现思路 1. 确定渲染的数据结构 2. 思考划分布局,总的有两个主要的模块:内容区域和按钮区域 2.1 内容区域保持宽度 ...

  2. 原生JS 的cookie和jq的cookie,

    COOKIE基础及应用:1.什么是COOKIE==>页面用来保存信息,比如:自动登录,记住用户名2.COOKIE的特性:  --同一个网站中,所有的页面共享同一套cookie  --数量,大小有 ...

  3. 原生js实现简洁的返回顶部组件

    本文内容相当简单,所以没有发布到博客园首页,如果你不幸看到,那只能是我这篇文章的荣幸,谢谢你的大驾光临~(本博客返回顶部的功能就使用的是这个组件) 返回顶部组件是一种极其常见的网页功能,需求简单:页面 ...

  4. 原生js操作cookie

    写cookie function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTim ...

  5. 原生js封装cookie获取、设置及删除

    使用cookie(key,value,options) 参数key,value,options(可选) function cookie(key,value,options){ if(typeof va ...

  6. 原生js对cookie的增删改查

    一.增 document.cookie = cname + "=" + cvalue + ";expires=" + expires + ";path ...

  7. 原生js登录创建cookie

    原生js创建cookie,功能:点击登录按钮时,将用户名.密码存为cookie:页面再次加载时,自动读取cookie中的用户名.密码. <html><head><titl ...

  8. js里cookie操作

    原生js操作cookie 创建和存储 cookie 在这个例子中我们要创建一个存储访问者名字的 cookie.当访问者首次访问网站时,他们会被要求填写姓名.名字会存储于 cookie 中.当访问者再次 ...

  9. 放弃jQuery,使用原生js吧!

    转自:http://itakeo.com/blog/2015/07/28/nojq/ 随着IE6.7.8的逐渐淘汰,HTML5的兴起,以及侧重点放在了移动端,jQuery可能变的不在那么重要,原生一样 ...

随机推荐

  1. CUMTCTF'2020 已做wp

    三天的比赛终于结束了,不知道有没有睡10个小时,感觉像中了魔一样,但也很享受这种感觉,除了没有能和我一起琢磨题目朋友.. 就最终结果而言还是有一些可惜,明明号称擅长web和misc反而是得分比例最小的 ...

  2. 一文了解.Net Core 3.1 Web API基础知识

    一.前言 随着近几年前后端分离.微服务等模式的兴起,.Net Core也似有如火如荼之势 ,自16年发布第一个版本到19年底的3.1 LTS版本,以及将发布的.NET 5,.NET Core一路更迭, ...

  3. 消息队列之事务消息,RocketMQ 和 Kafka 是如何做的?

    每个时代,都不会亏待会学习的人. 大家好,我是 yes. 今天我们来谈一谈消息队列的事务消息,一说起事务相信大家都不陌生,脑海里蹦出来的就是 ACID. 通常我们理解的事务就是为了一些更新操作要么都成 ...

  4. 【代码审计】PHP代码审计---基础记录

    PHP伪协议 PHP伪协议事实上是其支持的协议与封装协议,支持的种类有以下12种. * file:// - 访问本地文件系统 * http:// - 访问 HTTP(s) 网址 * ftp:// - ...

  5. [POI2010]PIL-Pilots 单调队列

    [POI2010]PIL-Pilots 题意: 给定一个序列和一个数值k,求一段连续最大区间是的最大值与最小值之差小于k: 思路: 因为要维护最大值和最小值并且连续,使用两个单调队列分别同时维护最大最 ...

  6. NOIP提高组2016 D2T3 【愤怒的小鸟】

    貌似还没有写过状压DP的题目,嗯,刚好今天考了,就拿出来写一写吧. 题目大意: 额,比较懒,这次就不写了... 思路分析: 先教大家一种判断题目是不是状压DP的方法吧. 很简单,那就是--看数据范围! ...

  7. pytest文档40-pytest.ini配置用例查找规则(面试题)

    前言 面试题:pytest如何执行不是test开头的用例?如执行 xxx_*.py这种文件的用例. pytest.ini 配置文件可以修改用例的匹配规则. pytest命令行参数 cmd打开输入pyt ...

  8. Python3.7有什么新变化

    https://docs.python.org/zh-cn/3/whatsnew/3.7.html

  9. MySQL字段添加注释,但不改变字段的类型

    之前在导数据库数据的时候,忘记将字段的注释导过来了.现在需要将所有字段都加上注释(崩溃).由于导数据的过程比较长,业务那边从原始数据库导出了一个 Excel,里面有所有字段的注释,然后让我们根据这个注 ...

  10. Centos7 安装python环境

    保留python2 找到python所在位置,把python指向python2.7备份 [root@sun /usr/bin]# cd ~ [root@sun ~]# whereis python p ...