学习通过JavaScript实现类似于淘宝的购物车效果,包括商品的单选、全选、删除、修改数量、价格计算、数目计算、预览等功能。

1. 实现兼容低版本IE的getElementsByClassName()方法

2. JS表格操作

3. 通过parseInt(),parseFloat()把字符串转换成数字

4. 通过toFixed()把数字格式化成指定位数的小数

5. 事件代理的运用

效果图:

border-collapse有两个值可以选择,分别是collapse和separate,就是合并边框和分离边框,分离边框之下又可以设置间距和边框样式

border-spacing:2em 4em;(设置右间距和下间距)

border-style:none solid dashed dotted;(分别设置上右下左的样式)

html结构:

 <table id="cartTable">
     <thead>
         <tr>
            <th><label><input class="check-all check" type="checkbox"/>&nbsp;全选</label></th>
             <th>商品</th>
             <th>单价</th>
             <th>数量</th>
             <th>小计</th>
             <th>操作</th>
         </tr>
     </thead>
     <tbody>
         <tr>
             <td class="checkbox"><input class="check-one check" type="checkbox" /></td>
             <td class="goods"><img src="data:images/1.jpg" alt="" /><span>Casio/卡西欧 EX-TR350</span></td>
             <td class="price">5999.88</td>
             <td class="count"><span class="reduce"></span><input class="count-input" type="text" value="1"/><span class="add">+</span></td>
             <td class="subtotal">5999.88</td>
             <td class="operation"><span class="delete">删除</span></td>
         </tr>
         <tr>
             <td class="checkbox"><input class="check-one check" type="checkbox" /></td>
             <td class="goods"><img src="data:images/2.jpg" alt="" /><span>Canon/佳能 PowerShot SX50 HS</span></td>
             <td class="price">3888.50</td>
             <td class="count"><span class="reduce"></span><input class="count-input" type="text" value="1"/><span class="add">+</span></td>
             <td class="subtotal">3888.50</td>
             <td class="operation"><span class="delete">删除</span></td>
         </tr>
         <tr>
             <td class="checkbox"><input class="check-one check" type="checkbox" /></td>
             <td class="goods"><img src="data:images/3.jpg" alt="" /><span>Sony/索尼 DSC-WX300</span></td>
             <td class="price">1428.50</td>
             <td class="count"><span class="reduce"></span><input class="count-input" type="text" value="1"/><span class="add">+</span></td>
             <td class="subtotal">1428.50</td>
             <td class="operation"><span class="delete">删除</span></td>
         </tr>
         <tr>
             <td class="checkbox"><input class="check-one check" type="checkbox" /></td>
             <td class="goods"><img src="data:images/4.jpg" alt="" /><span>Fujifilm/富士 instax mini 25</span></td>
             <td class="price">640.60</td>
             <td class="count"><span class="reduce"></span><input class="count-input" type="text" value="1"/><span class="add">+</span></td>
             <td class="subtotal">640.60</td>
             <td class="operation"><span class="delete">删除</span></td>
         </tr>
     </tbody>
 </table>
 <div class="foot" id="foot">
     <label class=" fl select-all"><input type="checkbox" class="check-all check" />&nbsp;全选</label>
     <a class="fl delete" id="deleteAll" href="javascript:;">删除</a>
     <div class="fr closing">结 算</div>
     <div class="fr total">合计:¥<span id="priceTotal">0.00</span></div>
     <div class="fr select" id="selected">已选商品<span id="selectedTotal">0</span>件<span class="arrow up">︽</span><span class="arrow down">︾</span></div>
     <div class="selected-view">
         <div id="selectedViewList" class="clearfix">
             <div><img src="data:images/1.jpg"><span>取消选择</span></div>
         </div>
         <span class="arrow">◆<span>◆</span></span>
     </div>
 </div>

css代码:

 *{
 ;
 ;
     }
     a{
         color: #666;
         text-decoration: none;
     }
     body{
         padding:20px;
         color: #666;
     }
     .fl{
         float: left;
     }
     .fr{
         float: right;
     }
     table{
         border-collapse: collapse;
 ;
 ;
         text-align: center;
         width: 937px;
     }
     th,td{
         border: 1px solid #cadeff;
     }
     th{
         background: #e2f2ff;
         border-top: 3px solid #a7cbff;
         height: 30px;
     }
     td{
         padding: 10px;
         color: #444;
     }
     tbody tr:hover{
         background: RGB(238,246,255);
     }
     .checkbox{width: 60px;}
     .goods{width: 300px;}
     .goods span{
         width: 180px;
         margin-top: 20px;
         text-align: left;
         float: left;
     }
     .price{width: 130px;}
     .count{width: 90px;}
     .count .add, .count input, .count .reduce{
         float: left;
         margin-left: -1px;
         position: relative;
 ;
     }
     .count .add, .count .reduce{
         height: 23px;
         width: 17px;
         border: 1px solid #e5e5e5;
         background: #f0f0f0;
         text-align: center;
         line-height: 23px;
         color: #444;
     }
     .count .add:hover, .count .reduce:hover{
         color: #f50;
 ;
         border-color: #f60;
         cursor: pointer;
     }
     .count input{
         width: 50px;
         height: 15px;
         line-height: 15px;
         border: 1px solid #aaa;
         color: #343434;
         text-align: center;
         padding: 4px 0;
         background-color: #fff;
 ;
     }
     .subtotal{
         width: 150px;
         color: red;
         font-weight: bold;
     }
     .operation{width: 80px;}
     .operation span:hover, .a:hover{
         cursor: pointer;
         color: red;
         text-decoration: underline;
     }
     img{
         width: 100px;
         height: 80px;
         margin-right: 10px;
         float: left;
     }
     .foot{
         width: 935px;
         margin-top: 10px;
         color: #666;
         height: 48px;
         border: 1px solid #c8c8c8;
         background-image: linear-gradient(RGB(241,241,241),RGB(226,226,226));
         position: relative;
 ;
     }
     .foot div, .foot a{
         line-height: 48px;
         height: 48px;
     }
     .foot .select-all{
         width: 100px;
         height: 48px;
         line-height: 48px;
         padding-left: 5px;
         color: #666;
     }
     .foot .closing{
         border-left: 1px solid #c8c8c8;
         width: 100px;
         text-align: center;
         color: #000;
         font-weight: bold;
         background: RGB(238,238,238);
         cursor: pointer;
     }
     .foot .total{
         margin: 0 20px;
         cursor: pointer;
     }
     .foot #priceTotal, .foot #selectedTotal{
         color: red;
         font-family: "微软雅黑";
         font-weight: bold;
     }
     .foot .select{
         cursor: pointer;
     }
     .foot .select .arrow{
         position: relative;
         top: -3px;
         margin-left: 3px;
     }
     .foot .select .down{
         position: relative;
         top: 3px;
         display: none;
     }
     .show .select .down{
         display: inline;
     }
     .show .select .up{
         display: none;
     }
     .foot .select:hover .arrow{
         color: red;
     }
     .foot .selected-view{
         width: 935px;
         border: 1px solid #c8c8c8;
         position: absolute;
         height: auto;
         background: #fff;
 ;
         bottom: 48px;
         left: -1px;
         display: none;
     }
     .show .selected-view{display: block;}
     .foot .selected-view div{height: auto;}
     .foot .selected-view .arrow{
         font-size: 16px;
         line-height: 100%;
         color: #c8c8c8;
         position: absolute;
         right: 330px;
         bottom: -9px;
     }
     .foot .selected-view .arrow span{
         color: #fff;
         position: absolute;
 ;
         bottom: 1px;
     }
     #selectedViewList{
         padding: 20px;
         margin-bottom: -20px;
     }
     #selectedViewList div{
         display: inline-block;
         position: relative;
         width: 100px;
         height: 80px;
         border: 1px solid #ccc;
         margin: 10px;
     }
     #selectedViewList div span{
         display: none;
         color: #fff;
         font-size: 12px;
         position: absolute;
 ;
 ;
         width: 60px;
         height: 18px;
         line-height: 18px;
         text-align: center;
         background: RGBA(0,0,0,.5);
         cursor: pointer;
     }
     #selectedViewList div:hover span{
         display: block;
     }

js部分:

1)实现商品的全选功能及数量和价格的计算

 var cartTable = document.getElementById('cartTable');
         var tr = cartTable.children[1].rows;//获取table下的tbody下的每一行
         var checkInputs = document.getElementsByClassName('check');
         var checkAllInputs = document.getElementsByClassName('check-all');
         var selectedTotal = document.getElementById('selectedTotal');
         var priceTotal = document.getElementById('priceTotal');
         //计算总数和价格
         function getTotal(){
             var selected = 0;
             var price = 0;
             for(var i=0;i < tr.length; i++){
                 if(tr[i].getElementsByTagName('input')[0].checked){
                     selected += parseInt(tr[i].getElementsByTagName('input')[1].value);
                     price += parseFloat(tr[i].cells[4].innerHTML);//cells属性为获得tr下面的td
                 }
             }
             selectedTotal.innerHTML = selected;
             priceTotal.innerHTML = price.toFixed(2);//保留两位小数
         }
         for(var i=0;i<checkInputs.length;i++){
             checkInputs[i].onclick = function(){
                 if(this.className === 'check-all check'){//如果点击的是全选按钮,则使所有按钮的状态和它相同
                     for(var j=0;j<checkInputs.length;j++){
                         checkInputs[j].checked = this.checked;
                     }
                 }
                 if(this.checked == false){//如果其中一个变为未选中状态,则使全选按钮取消选中
                     for(var i=0;i<checkAllInputs.length;i++){
                         checkAllInputs[i].checked = false;
                     }
                 }
                 getTotal();
             }
         }

2)点击已选商品实现商品预览浮层的功能

点击已选商品时会显示出已选择商品的列表

同时在getTotal()函数中增加新创建的div

js代码:

 function getTotal(){
             var selected = 0;
             var price = 0;
             var HTMLstr = '';
             for(var i=0;i < tr.length; i++){
                 if(tr[i].getElementsByTagName('input')[0].checked){
                     tr[i].className = 'on';
                     selected += parseInt(tr[i].getElementsByTagName('input')[1].value);
                     price += parseFloat(tr[i].cells[4].innerHTML);//cells属性为获得tr下面的td
                     HTMLstr += '<div><img src="'+ tr[i].getElementsByTagName('img')[0].src + '"><span>取消选择</span></div>';
                 }
                 else{
                     tr[i].className = '';
                 }
             }
             selectedTotal.innerHTML = selected;
             priceTotal.innerHTML = price.toFixed(2);//保留两位小数
             selectedViewList.innerHTML = HTMLstr;
             if(selected == 0){
                 foot.className = 'foot';
             }
         }
         for(var i=0;i<checkInputs.length;i++){
             checkInputs[i].onclick = function(){
                 if(this.className === 'check-all check'){//如果点击的是全选按钮,则使所有按钮的状态和它相同
                     for(var j=0;j<checkInputs.length;j++){
                         checkInputs[j].checked = this.checked;
                     }
                 }
                 if(this.checked == false){//如果其中一个变为未选中状态,则使全选按钮取消选中
                     for(var i=0;i<checkAllInputs.length;i++){
                         checkAllInputs[i].checked = false;
                     }
                 }
                 getTotal();
             }
         }

         selected.onclick = function(){
             if(foot.className == 'foot'){
                 if(selectedTotal.innerHTML != 0){
                     foot.className = 'foot show';
                 }
             }else{
                 foot.className = 'foot';
             }
         }

3)商品列表中的取消选择与事件代理

已选商品列表中没有appendChild的时候div和span都不存在,所以要使用事件代理。

  selectedViewList.onclick = function(e){
             var el = e.srcElement;
             if(el.className == 'del'){
                 var index = el.getAttribute('index');
                 var input = tr[index].getElementsByTagName('input')[0];
                 input.checked = false;
                 input.onclick();
             }
         }

4)实现增减商品数量及小计价格的计算

 //增减商品数量事件代理
         for(var i=0;i<tr.length;i++){
             tr[i].onclick = function(e){
                 e = e|| window.event;
                 var el = e.srcElement;
                 var cls = el.className;
                 var input = this.getElementsByTagName('input')[1];
                 var val = parseInt(input.value);
                 var reduce = this.getElementsByTagName('span')[1];
                 switch (cls){
                     case 'add':
                         input.value = val + 1;
                         reduce.innerHTML = '-';
                             getsubTotal(this);
                         break;
                     case 'reduce':
                         if(val > 1){
                             input.value = val - 1;
                             getsubTotal(this);
                         }else{
                             reduce.innerHTML = '';
                         }
                 }
                 getTotal();
             }
             tr[i].getElementsByTagName('input')[1].onkeyup = function(){
                 var val = parseInt(this.value);
                 var tr = this.parentNode.parentNode;//this指的是当前的input,其父节点的父节点就是当前的tr
                 var reduce = tr.getElementsByTagName('span')[1];
                 if(isNaN(val) || val < 1){
                     val = 1;
                 }
                 this.value = val;//保证输入框中都是大于1的纯数字
                 if(val <= 1){
                     reduce.innerHTML = '';
                 }
                else{
                     reduce.innerHTML = '-';
                 }
                 getsubTotal(tr);
                 getTotal();
             }
         }

5)实现删除商品功能

学会用for循环删除数组中的一些数据时要回置下标 i 。

  //删除商品
         deleteAll.onclick = function(){
             if(selectedTotal.innerHTML != '0'){
                 var conf = confirm("确定要删除所选商品吗");
                 if(conf){
                     for(var i=0;i<tr.length;i++){
                         var input = tr[i].getElementsByTagName('input')[0];
                         if(input.checked){
                             tr[i].parentNode.removeChild(tr[i]);
                             i --;//因为删除数组中的一个后,后面的索引就会向前移,此时要让i也向前移一个,回置下标i
                         }
                     }
                     getTotal();
                 }
             }
         }

JS实现购物车特效的更多相关文章

  1. event、fly.js、购物车特效

    先总结下区别: #鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条. event.clientX.event.clientY #鼠标相对于document文档区域的x ...

  2. 原生JS实现购物车结算功能代码+zepto版

    html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...

  3. 案例:用JS实现放大镜特效

    案例:用JS实现放大镜特效 案例:用JS实现放大镜特效

  4. JS实现购物车02

    需求使用JS实现购物车功能02 具体代码 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  5. JS实现购物车01

    需求 使用JS实现购物车功能01 具体代码 <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  6. vue.js实现购物车功能

    购物车是电商必备的功能,可以让用户一次性购买多个商品,常见的购物车实现方式有如下几种: 1. 用户更新购物车里的商品后,页面自动刷新. 2. 使用局部刷新功能,服务器端返回整个购物车的页面html 3 ...

  7. 用vue.js实现购物车功能

    购物车是电商必备的功能,可以让用户一次性购买多个商品,常见的购物车实现方式有如下几种: 1. 用户更新购物车里的商品后,页面自动刷新. 2. 使用局部刷新功能,服务器端返回整个购物车的页面html 3 ...

  8. js页面载入特效如何实现

    js页面载入特效如何实现 一.总结 一句话总结:可以加选择器(里面的字符串)作为参数,这样函数就可以针对不同选择器,就很棒了. 1.特效的原理是什么? 都是通过标签的位置和样式来实现特效的. 二.js ...

  9. 前端小插件之手写js循环滚动特效

    很多前端都离不开滚动的特效,调用插件繁琐,后期更改麻烦,考虑到这些因素,自己写了一套无限循环滚动的小特效. 首先滚动特效很好写,用css就可以完成,下面写一个基础css向上循环滚动特效 html &l ...

随机推荐

  1. spring mvc 返回页面数据

    handler package com.stone.controller; import java.util.Map; import javax.servlet.http.HttpServletReq ...

  2. DTLS 技术要点解析

    一.DTLS DTLS 是指 Datagram Transport Level Security,即数据报安全传输协议: 其提供了UDP 传输场景下的安全解决方案,能防止消息被窃听.篡改.身份冒充等问 ...

  3. TCP/IP协议族(一) HTTP简介、请求方法与响应状态码

    接下来想系统的回顾一下TCP/IP协议族的相关东西,当然这些东西大部分是在大学的时候学过的,但是那句话,基础的东西还是要不时的回顾回顾的.接下来的几篇博客都是关于TCP/IP协议族的,本篇博客就先简单 ...

  4. js面试题-2

    // 1.截取字符串 var aa = "abcd"; console.log(aa.substr(,)); var str = "qweda"; consol ...

  5. PLSQL DEVELOPER 使用的一些技巧【转】

    1.登录后默认自动选中My Objects 默认情况下,PLSQL Developer登录后,Brower里会选择All objects,如果你登录的用户是dba,要展开tables目录,正常情况都需 ...

  6. Use Prerender to improve AngularJS SEO

    Use Prerender to improve AngularJS SEO Nuget Package of ASP.NET MVC HttpModule for prerender.io: Ins ...

  7. IP地址和硬件地址 ARP协议

    ip地址使用在网络层以上,是一个逻辑地址,物理地址是数据链路层和物理层使用的 在发送数据的时候,数据是从上层往下层发送的,通过tcp报文->ip数据报->mac数据帧 IP地址放在数据报的 ...

  8. MySQL索引创建、删除、查看

    主键索引   PRIMARY KEY索引仅是一个具有名称PRIMARY的UNIQUE索引.这表示一个表只能包含一个PRIMARY KEY,因为一个表中不可能具有两个同名的索引. ALTER TABLE ...

  9. Windows环境下安装配置Teamcity配合git自动发布mvc,webapi站点

    以下是本人配置Teamcity具体环境和步骤,只实现了项目发布,打包.Nodejs npm gulp没有配置成功,后期补上. 1 环境安装 本人使用的是windows7 sp1 64位系统,(.net ...

  10. wpf中子窗口的几个问题

    今天研究了一下wpf中的窗口,写这篇文章来总结一下今天的收获.(转载请注明出处~) 总所周知,窗口是windows系统中十分重要的一个元素(从名字上就能体现出来),而一个应用程序总是包含很多窗口(主窗 ...