Home  >  Article  >  Web Front-end  >  JS implementation of simple shopping cart function code analysis

JS implementation of simple shopping cart function code analysis

php中世界最好的语言
php中世界最好的语言Original
2018-05-23 11:22:585402browse

This time I will bring you a code analysis of JS to implement a simple shopping cart function. What are the precautions for JS to implement a simple shopping cart function? The following is a practical case, let’s take a look.

We must all be familiar with the function of the product shopping cart. Whenever we purchase products on a certain website, which product we like, we will add it to the shopping cart and finally settle. The shopping cart function facilitates consumers to manage products. They can add products, delete products, select one or several products in the shopping cart, and the final total price of the products will also change with the consumer's operations.

Now, the author has made a simple implementation of the shopping cart, which can realize most of the functions of the real shopping cart. In this example, BOM operations, DOM operations, table operations, cookies, json and other knowledge points in JavaScript are used. At the same time, a three-layer architecture is used to design the shopping cart, which has strong comprehensive application of JavaScript and is suitable for beginners of JavaScript. There are certain benefits to advancing.

Please take a look at the renderings of the homepage:

Now that readers have understood the renderings of the homepage, I am attaching the html code of the homepage here for your reference. For readers' reference, it is recommended that readers write code according to their own ideas.

Please look at the html code:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8" />
 <title>商品列表页面</title>
 <!--商品列表样式表-->
 <link rel="stylesheet" type="text/css" href="../css/index.css" rel="external nofollow" />
 <!--cookie操作的js库-->
 <script src="../js/cookie.js" type="text/javascript" charset="utf-8"></script>
 </head>
 <body>
 <p class="container">
  <h1>商品列表</h1>
  <p class="mycar">
  <a href="cart.html" rel="external nofollow" >我的购物车</a><i id="ccount">0</i>
  </p>
  <p class="list">
  <dl pid="1001">
   <dt>
   <img src="../images/p1.jpg" />
   </dt>
   <dd>智能手表</dd>
   <dd>酷黑,棒,棒,棒,棒</dd>
   <dd>¥<span>998</span></dd>
   <dd>
   <button>添加购物车</button>
   </dd>
  </dl>
  <dl pid="1002">
   <dt>
   <img src="../images/p2.jpg" />
   </dt>
   <dd>智能手机001</dd>
   <dd>金红色,酷酷酷酷</dd>
   <dd>¥<span>1998</span></dd>
   <dd>
   <button>添加购物车</button>
   </dd>
  </dl>
  <dl pid="1003">
   <dt>
   <img src="../images/p3.jpg" />
   </dt>
   <dd>华为手机002</dd>
   <dd>帅帅帅帅帅帅帅帅帅帅</dd>
   <dd>¥<span>998</span></dd>
   <dd>
   <button>添加购物车</button>
   </dd>
  </dl>
  <dl pid="1004">
   <dt>
   <img src="../images/p4.jpg" />
   </dt>
   <dd>华为手机003</dd>
   <dd>杠杠的</dd>
   <dd>¥<span>2000</span></dd>
   <dd>
   <button>添加购物车</button>
   </dd>
  </dl>
  </p>
 </p>
 <!--
  描述:数据访问层,操作本地数据的模块
 -->
 <script type="text/javascript" src="../js/server.js"></script>
 <!--
  描述:本页面的js操作
 -->
 <script type="text/javascript" src="../js/index.js"></script>
 </body>
</html>
After the html structure code is available, you can perform CSS performance design on the homepage. I will not explain too much about CSS here.

After we design the homepage, we can perform DOM operations related to the homepage, including adding button click events, cookie and json applications. Cookies are mainly used to share current data with the shopping cart. Easy to operate. Please look at the related javascript code:

This is the index.js code, mainly related to the homepage operations:

/*
 思路:
 第一步:获取所要操作的节点对象
 第二步:当页面加载完后,需要计算本地cookie存了多少【个】商品,把个数赋值给ccount
 第三步:为每一个商品对应的添加购物车按钮绑定一个点击事件onclick
  更改本地的cookie
  获取当前商品的pid
  循环遍历本地的cookie转换后的数组,取出每一个对象的pid进行对比,若相等则该商品不是第一次添加
  从购物车中取出该商品,然后更pCount值追加1
  否则:创建一个新的对象,保存到购物中。同时该商品的数量为1
 */
var ccount = document.getElementById("ccount"); //显示商品总数量的标签节点对象
var btns = document.querySelectorAll(".list dl dd button"); //所有的购物车按钮
//约定好用名称为datas的cookie来存放购物车里的数据信息 datas里所存放的就是一个json字符串
var listStr = cookieObj.get("datas");
/*判断一下本地是否有一个购物车(datas),没有的话,创建一个空的购物车,有的话就直接拿来使用*/
if(!listStr) { //没有购物车 datas json
 cookieObj.set({
 name: "datas",
 value: "[]"
 });
 listStr = cookieObj.get("datas");
}
var listObj = JSON.parse(listStr); //数组
/*循环遍历数组,获取每一个对象中的pCount值相加总和*/
var totalCount = 0; //默认为0
for(var i = 0, len = listObj.length; i < len; i++) {
 totalCount = listObj[i].pCount + totalCount;
}
ccount.innerHTML = totalCount;
/*循环为每一个按钮添加点击事件*/
for(var i = 0, len = btns.length; i < len; i++) {
 btns[i].onclick = function() {
 var dl = this.parentNode.parentNode;
 var pid = dl.getAttribute("pid");//获取自定义属性
 var arrs = dl.children;//获取所有子节点
 if(checkObjByPid(pid)) {
  listObj = updateObjById(pid, 1)
 } else {
  var imgSrc = arrs[0].firstElementChild.src;
  var pName = arrs[1].innerHTML;
  var pDesc = arrs[2].innerHTML;
  var price = arrs[3].firstElementChild.innerHTML;
  var obj = {
  pid: pid,
  pImg: imgSrc,
  pName: pName,
  pDesc: pDesc,
  price: price,
  pCount: 1
  };
  listObj.push(obj)
  listObj = updateData(listObj);
 }
 ccount.innerHTML = getTotalCount();
 }
}
This is the cookie.js code, mainly related to cookie settings and acquisition The operation is encapsulated using the singleton

design pattern . Please see the code:

/*
 单例设计模式
 完整形式:[]中是可选项
 document.cookie = “name=value[;expires=date][;path=path-to-resource][;domain=域名][;secure]”
*/
var cookieObj = {
 /*
 增加或修改cookie
 参数:o 对象{}
 name:string cookie名
 value:string cookie值
 expires:Date对象 过期时间
 path:string 路径限制
 domain:string 域名限制
 secure:boolean true https false或undeinfed 
 */
 set: function(o) {
 var cookieStr = encodeURIComponent(o.name) + "=" + encodeURIComponent(o.value);
 if(o.expires) {
  cookieStr += ";expires=" + o.expires;
 }
 if(o.path) {
  cookieStr += ";path=" + o.path;
 }
 if(o.domain) {
  cookieStr += ";domain=" + o.domain;
 }
 if(o.secure) {
  cookieStr += ";secure";
 }
 document.cookie = cookieStr;
 },
 /*
 删除
 参数:n string cookie的名字
 */
 del: function(n) {
 var date = new Date();
 date.setHours(-1);
 //this代表的是当前函数的对象
 this.set({
  name: n,
  expires: date
 });
 },
 /*查找*/
 get: function(n) {
 n = encodeURIComponent(n);
 var cooikeTotal = document.cookie;
 var cookies = cooikeTotal.split("; ");
 for(var i = 0, len = cookies.length; i < len; i++) {
  var arr = cookies[i].split("=");
  if(n == arr[0]) {
  return decodeURIComponent(arr[1]);
  }
 }
 }
}
The following is the server.js code, which mainly encapsulates various operations in the shopping cart, such as Count the number of products, update and obtain local data, and other operations to facilitate code management. Please see the code:

/*
 功能:查看本地数据中是否含有指定的对象(商品),根据id
 参数:id:商品的标识
 */
function checkObjByPid(id) {
 var jsonStr = cookieObj.get("datas");
 var jsonObj = JSON.parse(jsonStr);
 var isExist = false;
 for(var i = 0, len = jsonObj.length; i < len; i++) {
 if(jsonObj[i].pid == id) {
  isExist = true;
  break;
 }
 }
 return isExist; //return false;
}
/*
 功能:更新本地数据
 参数:arr 数组对象
 返回一个值:最新的本地转换后的数组对象
 * */
function updateData(arr) {
 var jsonStr = JSON.stringify(arr);
 cookieObj.set({
 name: "datas",
 value: jsonStr
 });
 jsonStr = cookieObj.get("datas");
 return JSON.parse(jsonStr);
}
/*
 获取商品的总数量
 返回:数字
 */
function getTotalCount() {
 /*循环遍历数组,获取每一个对象中的pCount值相加总和*/
 var totalCount = 0; //默认为0
 var jsonStr = cookieObj.get("datas");
 var listObj = JSON.parse(jsonStr);
 for(var i = 0, len = listObj.length; i < len; i++) {
 totalCount = listObj[i].pCount + totalCount;
 }
 return totalCount;
}
/*
 更新本地数据根据pid
 id:商品的标识
 */
function updateObjById(id, num) {
 var jsonStr = cookieObj.get("datas");
 var listObj = JSON.parse(jsonStr);
 for(var i = 0, len = listObj.length; i < len; i++) {
 if(listObj[i].pid == id) {
  listObj[i].pCount = listObj[i].pCount + num;
  break;
 }
 }
 return updateData(listObj)
}
/*
 获取本地数据
 返回 数组对象
 * */
function getAllData() {
 var jsonStr = cookieObj.get("datas");
 var listObj = JSON.parse(jsonStr);
 return listObj;
}
function deleteObjByPid(id) {
 var lisObj = getAllData();
 for(var i = 0, len = lisObj.length; i < len; i++) {
 if(lisObj[i].pid == id) {
  lisObj.splice(i, 1);
  break;
 }
 }
 updateData(lisObj);
 return lisObj;
}
Because the above code involves some operations after entering the shopping cart, readers may be confused after reading it. Don’t worry, please see the analysis after clicking to enter my shopping cart below.

Please see the rendering:

The author clicked on three products on the homepage, a total of seven times, and the corresponding products appeared in the shopping cart and price calculations. I believe readers can understand all kinds of information along the way at a glance. Please look at the html code of this shopping cart:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>购物车</title>
 <!--购物车样式表-->
 <link rel="stylesheet" type="text/css" href="../css/cart.css" rel="external nofollow" />
 <!--操作cookie的js文件-->
 <script type="text/javascript" src="../js/cookie.js"></script>
 </head>
 <body>
 <p class="container">
  <h1>购物车</h1>
  <h3><a href="index.html" rel="external nofollow" >返回商品列表页面</a></h3>
  <table id="table" border="1" cellspacing="0" cellpadding="0" class="hide">
  <thead>
   <tr>
   <th>
    <input type="checkbox" id="allCheck" class="ck" />全选
   </th>
   <th>
    图片
   </th>
   <th>
    描述
   </th>
   <th>
    数量
   </th>
   <th>
    单价
   </th>
   <th>
    小计
   </th>
   <th>
    操作
   </th>
   </tr>
  </thead>
  <tbody id="tbody">
   <!--
   <tr>
   <td>
    <input type="checkbox" class="ck" />
   </td>
   <td>
    <img src="../images/p1.jpg" alt="" />
   </td>
   <td>
    酷黑,棒棒棒棒
   </td>
   <td>
    <button class="down">-</button><input type="text" value="1" readonly="readonly" /><button class="up">+</button>
   </td>
   <td>
    ¥<span>111</span>
   </td>
   <td>
    ¥<span>111</span>
   </td>
   <td>
    <button class="del" >删除</button>
   </td>
   </tr>
   -->
  </tbody>
  </table>
  <p class="box" id="box">购物车里没有任何商品</p>
  <h2 id="h2" class="">总价格:¥<span id="totalPrice">0</span></h2>
 </p>
 <script src="../js/server.js" type="text/javascript" charset="utf-8"></script>
 <!--操作购物车页面的cart.js-->
 <script src="../js/cart.js"></script>
 </body>
</html>
After designing the relevant performance of the shopping cart, we need to design the javascript behavior. Please look at the cart.js code related to this page:

/*
 思路:
 第一步:当页面加载完后,根据本地的数据,动态生成表格(购物车列表)
  获取所要操作的节点对象
  判断购物车中是否有数据?
  有:
   显示出购物列表
  没有:
   提示购物车为空
 第二步:当购物车列表动态生成后,获取tbody里所有 的checkeBox标签节点对象,看那个被选中就获取对应行小计进行总价格运算。
 第三步:
  为每一个checkbox添加一个onchange事件,根据操作更改总价格
 第四步:全选
 第五步:
  为加减按钮添加一个鼠标点击事件
  更改该商品的数量
 第六步:删除
  获取所有的删除按钮
  为删除按钮添加一个鼠标点击事件
  删除当前行,并更新本地数据
 */
var listObj = getAllData();
var table = document.getElementById("table")
var box = document.getElementById("box")
var tbody = document.getElementById("tbody");
var totalPrice = document.getElementById("totalPrice");
var allCheck = document.getElementById("allCheck");
if(listObj.length == 0) { //购物车为空
 box.className = "box";
 table.className = "hide";
} else {
 box.className = "box hide";
 table.className = "";
 for(var i = 0, len = listObj.length; i < len; i++) {
 var tr = document.createElement("tr");
 tr.setAttribute("pid", listObj[i].pid);
  //{"pid":值,"pImg":值,"pName":值,"pDesc":值,"price":值,"pCount":1},
 tr.innerHTML = '<td>' +
  '<input type="checkbox" class="ck" />' +
  '</td>' +
  '<td>' +
  '<img src="&#39; + listObj[i].pImg + &#39;" alt="" />' +
  '</td>' +
  '<td>' +
  listObj[i].pDesc +
  '</td>' +
  '<td>' +
  '<button class="down">-</button><input type="text" value="&#39; + listObj[i].pCount + &#39;" readonly="readonly" /><button class="up">+</button>' +
  '</td>' +
  '<td>' +
  '¥<span>' + listObj[i].price + '</span>' +
  '</td>' +
  '<td>' +
  '¥<span>' + listObj[i].price * listObj[i].pCount + '</span>' +
  '</td>' +
  '<td>' +
  '<button class="del" >删除</button>' +
  '</td>';
 tbody.appendChild(tr);
 }
}
/*
 功能:计算总价格
 */
var cks = document.querySelectorAll("tbody .ck");
function getTotalPrice() {
 cks = document.querySelectorAll("tbody .ck");
 var sum = 0;
 for(var i = 0, len = cks.length; i < len; i++) {
 if(cks[i].checked) { //如果当前被选中
  var tr = cks[i].parentNode.parentNode;
  var temp = tr.children[5].firstElementChild.innerHTML;
  sum = Number(temp) + sum;
 }
 }
 return sum;
}
/*循环遍历为每一个checkbox添加一个onchange事件*/
for(var i = 0, len = cks.length; i < len; i++) {
 cks[i].onchange = function() {
 checkAllChecked();
 totalPrice.innerHTML = getTotalPrice();
 }
}
/*全选实现*/
allCheck.onchange = function() {
 if(this.checked) {
 for(var i = 0, len = cks.length; i < len; i++) {
  cks[i].checked = true;
 }
 } else {
 for(var i = 0, len = cks.length; i < len; i++) {
  cks[i].checked = false;
 }
 }
 totalPrice.innerHTML = getTotalPrice();
}
var downs = document.querySelectorAll(".down"); //一组减的按钮
var ups = document.querySelectorAll(".up"); //一组加的按钮
var dels = document.querySelectorAll(".del"); //一组删除按钮
for(var i = 0, len = downs.length; i < len; i++) {
 downs[i].onclick = function() {
 var txtObj = this.nextElementSibling;//下一个兄弟节点
 var tr = this.parentNode.parentNode;
 var pid = tr.getAttribute("pid");
 txtObj.value = txtObj.value - 1;
 if(txtObj.value < 1) {
  txtObj.value = 1;
  updateObjById(pid, 0)
 } else {
  updateObjById(pid, -1)
 }
 tr.children[0].firstElementChild.checked = true;
 checkAllChecked();
 var price = tr.children[4].firstElementChild.innerHTML;
 tr.children[5].firstElementChild.innerHTML = price * txtObj.value;
 totalPrice.innerHTML = getTotalPrice();
 }
 ups[i].onclick = function() {
 var txtObj = this.previousElementSibling;//上一个兄弟节点
 var tr = this.parentNode.parentNode;
 var pid = tr.getAttribute("pid");
 txtObj.value = Number(txtObj.value) + 1;
 updateObjById(pid, 1)
 tr.children[0].firstElementChild.checked = true;
 checkAllChecked()
 var price = tr.children[4].firstElementChild.innerHTML;
 tr.children[5].firstElementChild.innerHTML = price * txtObj.value;
 totalPrice.innerHTML = getTotalPrice();
 }
 dels[i].onclick = function() {
 var tr = this.parentNode.parentNode;
 var pid = tr.getAttribute("pid")
 if(confirm("确定删除?")) {
  //remove() 自杀
  tr.remove();
  listObj = deleteObjByPid(pid);
 }
 if(listObj.length == 0) { //购物车为空
  box.className = "box";
  table.className = "hide";
 } else {
  box.className = "box hide";
  table.className = "";
 }
 totalPrice.innerHTML = getTotalPrice();
 }
}
/*检测是否要全选*/
function checkAllChecked() {
 var isSelected = true; //全选是否会选中
 for(var j = 0, len = cks.length; j < len; j++) {
 if(cks[j].checked == false) {
  isSelected = false;
  break;
 }
 }
 allCheck.checked = isSelected;
}
The above code completes the relevant operations in the shopping cart, such as price calculation, product quantity replacement,

product deletion and other operations.

At this point we have completed most of the functions of the shopping cart. We have comprehensively applied html, css, BOM, DOM, json, cookie, etc. I believe that readers will learn more about their own javascript after understanding it. Furthermore, most of the code involved in this example is posted on this page, and some code resources are not shown to readers. Readers can click on the resource link below to download all the code and picture materials of this example. This example is compiled and run using the HBuilder compiler and involves cookie operations. Readers are asked to install the server themselves or add it to HBuilder to run and view.

I believe you have mastered the method after reading the case in this article. For more exciting information, please pay attention to other related articles on the php Chinese website!

Recommended reading:

Use vue.js to implement recipe editing

How to implement markdown adaptation of the mpvue applet

The above is the detailed content of JS implementation of simple shopping cart function code analysis. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn