原生JS结合cookie实现商品评分组件

组件样式效果:

原生JS结合cookie实现商品评分组件_第1张图片

再次访问记录用户上次操作:

原生JS结合cookie实现商品评分组件_第2张图片

开发思路如下:

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

你可能感兴趣的