搜索
首页web前端js教程使用JS实现购物车功能步骤详解

使用JS实现购物车功能步骤详解

May 12, 2018 am 10:13 AM
javascript实现购物车

这次给大家带来使用JS实现购物车功能步骤详解,使用JS实现购物车功能的注意事项有哪些,下面就是实战案例,一起来看一下。

我们肯定都很熟悉商品购物车这一功能,每当我们在某宝某东上购买商品的时候,看中了哪件商品,就会加入购物车中,最后结算。购物车这一功能,方便消费者对商品进行管理,可以添加商品,删除商品,选中购物车中的某一项或几项商品,最后商品总价也会随着消费者的操作随着变化。

现在,笔者对购物车进行了简单实现,能够实现真实购物车当中的大部分功能。在本示例当中,用到了javascript中BOM操作,DOM操作,表格操作,cookie,json等知识点,同时,采用三层架构方式对购物车进行设计,对javascript的综合应用较强,对javascript初学者进阶有一定的益处。

请看主页效果图:

现在读者已经对主页的效果图进行了了解,我在这里附上主页的html代码,供读者参考,建议读者根据自己的思路写代码。

请看html代码:

<!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>

html结构代码有了之后,就可以对主页进行css表现设计,这里不对css进行过多讲解。

我们对主页进行设计之后,就可以进行与主页相关的DOM操作,涉及到添加按钮的点击事件,cookie和json的应用,cookie主要为了让当前数据与购物车进行共享,以方便操作。请看与之相关的javascript代码:

这是index.js代码,主要是主页的相关操作:

/*
 思路:
 第一步:获取所要操作的节点对象
 第二步:当页面加载完后,需要计算本地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();
 }
}

这是cookie.js的代码,主要涉及cookie的设置获取操作,采用单例设计模式进行了封装设计,请看代码:

/*
 单例设计模式
 完整形式:[]中是可选项
 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]);
  }
 }
 }
}

下面的是server.js代码,主要对购物车中各种操作进行了封装,比如商品个数统计,更新获取本地数据等操作,方便代码管理,请看代码:

/*
 功能:查看本地数据中是否含有指定的对象(商品),根据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;
}

因为上述代码中涉及了进入购物车后的一些操作,读者看了之后可能会感动疑惑,不用担心,下面请看点击进入我的购物车之后的分析。

请看效果图: 

笔者在主页中点击了三种商品,共点击了七次,在购物车中出现了相应商品以及价格计算。对于途中的各种信息,相信读者一目了然。请看本购物车的html代码:

<!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>

在对购物车进行相关的表现设计之后,既要进行javascript行为设计,请看与本页相关的cart.js代码:

/*
 思路:
 第一步:当页面加载完后,根据本地的数据,动态生成表格(购物车列表)
  获取所要操作的节点对象
  判断购物车中是否有数据?
  有:
   显示出购物列表
  没有:
   提示购物车为空
 第二步:当购物车列表动态生成后,获取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;
}

上述代码完成了购物车中的相关操作,比如价格计算,商品数量更换,商品删除等操作。

到这里我们已经完成了购物车的大部分功能,我们对html,css, BOM,DOM,json,cookie等进行了综合应用,相信读者理解之后一定会对自己的javascript学习更进一步,本示例中涉及的大部分代码都在本页中贴出,部分代码资源未向读者展示,读者可以点击下面的资源链接,下载本示例的全部代码及图片资料。本示例采用HBuilder编译器编译运行,涉及cookie操作,请读者自行安装服务器或者添加到HBuilder中运行查看。

资源链接:购物车全部资源下载

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

php curl批量控制并发异步操作

PHP快速实现数组去重方法

以上是使用JS实现购物车功能步骤详解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Python vs. JavaScript:学习曲线和易用性Python vs. JavaScript:学习曲线和易用性Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python vs. JavaScript:社区,图书馆和资源Python vs. JavaScript:社区,图书馆和资源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C到JavaScript:所有工作方式从C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript引擎:比较实施JavaScript引擎:比较实施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

使用Next.js(后端集成)构建多租户SaaS应用程序使用Next.js(后端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

如何使用Next.js(前端集成)构建多租户SaaS应用程序如何使用Next.js(前端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript:探索网络语言的多功能性JavaScript:探索网络语言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),