学习通过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. HTML5获取当前的经纬度坐标

    使用IE10可以查看出结果:chrome和ff都没有正确显示: <!DOCTYPE html> <html lang="en"> <head> ...

  2. Docker - 用Flannel跨主机

    试了下比较流行的几种SDN,感觉flannel还是比较好用,这里简单记录一下. 用的是virtualbox,3个机器,分别为: genesis : inet 192.168.99.103/24 brd ...

  3. MyBatis:学习笔记(3)——关联查询

    MyBatis:学习笔记(3)--关联查询 关联查询 理解联结 SQL最强大的功能之一在于我们可以在数据查询的执行中可以使用联结,来将多个表中的数据作为整体进行筛选. 模拟一个简单的在线商品购物系统, ...

  4. SQL CRUD 简单查询

    identity 自增长 primary key 主键 unique 唯一键 not null 非空 references 外键(引用) 1.删除表 drop table Student 2.修改表 ...

  5. ArcGIS制图表达Representation-制图表达介绍

    ArcGIS制图表达技术-制图表达介绍 by 李远祥 在基于GIS数据的制图中,大部分都是使用的数据+符号应用的这种模式.这种模式已经被应用很多年,而且也是非常成熟.对应在ArcGIS体系里面,就是数 ...

  6. 前端基本知识(一):W3C标准&&冒泡事件,捕获事件,W3C DOM对象模型,对比分析

    W3C标准是万维网联盟, 其他的可以参考万维网版本的更新内容 一.W3C标准 二.W3C DOM事件 三.冒泡事件 四.捕获事件 一.W3C标准 其实网页是由三分部组成:1.结构(structure) ...

  7. iOS 创建OpenGL 环境的思考

    关于如何从头开始创建环境,可以参考大神的博文OpenGL ES 3.0 数据可视化 0:Hello world,本文只是补充一些我在实践中的一些思考. CAEAGLLayer If you plan ...

  8. OSGI框架中通过BundleContext对象对服务的注册与引用

    BundleActivator 在每个Bundle新建时都会默认生成Activator类,该类实现了BundleActivator类,实现了其start()和stop()两个方法 BundleCont ...

  9. angularJS+requireJS实现controller及directive的按需加载

    最近因为项目的比较大,需要加载的js文件较多,为了提高首屏页面的加载速度,需要对js文件进行按需加载,然后网上参考了一些资料,自己也深入研究一番之后,实现了按需加载控制器js文件及指令js文件的效果: ...

  10. java程序测试之字节流

    package filestream; import java.io.FileInputStream; import java.io.FileNotFoundException; import jav ...