JS实现购物车特效
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结构:
1 <table id="cartTable"> 2 <thead> 3 <tr> 4 <th><label><input class="check-all check" type="checkbox"/> 全选</label></th> 5 <th>商品</th> 6 <th>单价</th> 7 <th>数量</th> 8 <th>小计</th> 9 <th>操作</th> 10 </tr> 11 </thead> 12 <tbody> 13 <tr> 14 <td class="checkbox"><input class="check-one check" type="checkbox" /></td> 15 <td class="goods"><img src="images/1.jpg" alt="" /><span>Casio/卡西欧 EX-TR350</span></td> 16 <td class="price">5999.88</td> 17 <td class="count"><span class="reduce"></span><input class="count-input" type="text" value="1"/><span class="add">+</span></td> 18 <td class="subtotal">5999.88</td> 19 <td class="operation"><span class="delete">删除</span></td> 20 </tr> 21 <tr> 22 <td class="checkbox"><input class="check-one check" type="checkbox" /></td> 23 <td class="goods"><img src="images/2.jpg" alt="" /><span>Canon/佳能 PowerShot SX50 HS</span></td> 24 <td class="price">3888.50</td> 25 <td class="count"><span class="reduce"></span><input class="count-input" type="text" value="1"/><span class="add">+</span></td> 26 <td class="subtotal">3888.50</td> 27 <td class="operation"><span class="delete">删除</span></td> 28 </tr> 29 <tr> 30 <td class="checkbox"><input class="check-one check" type="checkbox" /></td> 31 <td class="goods"><img src="images/3.jpg" alt="" /><span>Sony/索尼 DSC-WX300</span></td> 32 <td class="price">1428.50</td> 33 <td class="count"><span class="reduce"></span><input class="count-input" type="text" value="1"/><span class="add">+</span></td> 34 <td class="subtotal">1428.50</td> 35 <td class="operation"><span class="delete">删除</span></td> 36 </tr> 37 <tr> 38 <td class="checkbox"><input class="check-one check" type="checkbox" /></td> 39 <td class="goods"><img src="images/4.jpg" alt="" /><span>Fujifilm/富士 instax mini 25</span></td> 40 <td class="price">640.60</td> 41 <td class="count"><span class="reduce"></span><input class="count-input" type="text" value="1"/><span class="add">+</span></td> 42 <td class="subtotal">640.60</td> 43 <td class="operation"><span class="delete">删除</span></td> 44 </tr> 45 </tbody> 46 </table> 47 <div class="foot" id="foot"> 48 <label class=" fl select-all"><input type="checkbox" class="check-all check" /> 全选</label> 49 <a class="fl delete" id="deleteAll" href="javascript:;">删除</a> 50 <div class="fr closing">结 算</div> 51 <div class="fr total">合计:¥<span id="priceTotal">0.00</span></div> 52 <div class="fr select" id="selected">已选商品<span id="selectedTotal">0</span>件<span class="arrow up">︽</span><span class="arrow down">︾</span></div> 53 <div class="selected-view"> 54 <div id="selectedViewList" class="clearfix"> 55 <div><img src="images/1.jpg"><span>取消选择</span></div> 56 </div> 57 <span class="arrow">◆<span>◆</span></span> 58 </div> 59 </div>
css代码:
1 *{ 2 margin: 0; 3 padding: 0; 4 } 5 a{ 6 color: #666; 7 text-decoration: none; 8 } 9 body{ 10 padding:20px; 11 color: #666; 12 } 13 .fl{ 14 float: left; 15 } 16 .fr{ 17 float: right; 18 } 19 table{ 20 border-collapse: collapse; 21 border-spacing: 0; 22 border: 0; 23 text-align: center; 24 width: 937px; 25 } 26 th,td{ 27 border: 1px solid #cadeff; 28 } 29 th{ 30 background: #e2f2ff; 31 border-top: 3px solid #a7cbff; 32 height: 30px; 33 } 34 td{ 35 padding: 10px; 36 color: #444; 37 } 38 tbody tr:hover{ 39 background: RGB(238,246,255); 40 } 41 .checkbox{width: 60px;} 42 .goods{width: 300px;} 43 .goods span{ 44 width: 180px; 45 margin-top: 20px; 46 text-align: left; 47 float: left; 48 } 49 .price{width: 130px;} 50 .count{width: 90px;} 51 .count .add, .count input, .count .reduce{ 52 float: left; 53 margin-left: -1px; 54 position: relative; 55 z-index: 0; 56 } 57 .count .add, .count .reduce{ 58 height: 23px; 59 width: 17px; 60 border: 1px solid #e5e5e5; 61 background: #f0f0f0; 62 text-align: center; 63 line-height: 23px; 64 color: #444; 65 } 66 .count .add:hover, .count .reduce:hover{ 67 color: #f50; 68 z-index: 3; 69 border-color: #f60; 70 cursor: pointer; 71 } 72 .count input{ 73 width: 50px; 74 height: 15px; 75 line-height: 15px; 76 border: 1px solid #aaa; 77 color: #343434; 78 text-align: center; 79 padding: 4px 0; 80 background-color: #fff; 81 z-index: 2; 82 } 83 .subtotal{ 84 width: 150px; 85 color: red; 86 font-weight: bold; 87 } 88 .operation{width: 80px;} 89 .operation span:hover, .a:hover{ 90 cursor: pointer; 91 color: red; 92 text-decoration: underline; 93 } 94 img{ 95 width: 100px; 96 height: 80px; 97 margin-right: 10px; 98 float: left; 99 } 100 .foot{ 101 width: 935px; 102 margin-top: 10px; 103 color: #666; 104 height: 48px; 105 border: 1px solid #c8c8c8; 106 background-image: linear-gradient(RGB(241,241,241),RGB(226,226,226)); 107 position: relative; 108 z-index: 8; 109 } 110 .foot div, .foot a{ 111 line-height: 48px; 112 height: 48px; 113 } 114 .foot .select-all{ 115 width: 100px; 116 height: 48px; 117 line-height: 48px; 118 padding-left: 5px; 119 color: #666; 120 } 121 .foot .closing{ 122 border-left: 1px solid #c8c8c8; 123 width: 100px; 124 text-align: center; 125 color: #000; 126 font-weight: bold; 127 background: RGB(238,238,238); 128 cursor: pointer; 129 } 130 .foot .total{ 131 margin: 0 20px; 132 cursor: pointer; 133 } 134 .foot #priceTotal, .foot #selectedTotal{ 135 color: red; 136 font-family: "微软雅黑"; 137 font-weight: bold; 138 } 139 .foot .select{ 140 cursor: pointer; 141 } 142 .foot .select .arrow{ 143 position: relative; 144 top: -3px; 145 margin-left: 3px; 146 } 147 .foot .select .down{ 148 position: relative; 149 top: 3px; 150 display: none; 151 } 152 .show .select .down{ 153 display: inline; 154 } 155 .show .select .up{ 156 display: none; 157 } 158 .foot .select:hover .arrow{ 159 color: red; 160 } 161 .foot .selected-view{ 162 width: 935px; 163 border: 1px solid #c8c8c8; 164 position: absolute; 165 height: auto; 166 background: #fff; 167 z-index: 9; 168 bottom: 48px; 169 left: -1px; 170 display: none; 171 } 172 .show .selected-view{display: block;} 173 .foot .selected-view div{height: auto;} 174 .foot .selected-view .arrow{ 175 font-size: 16px; 176 line-height: 100%; 177 color: #c8c8c8; 178 position: absolute; 179 right: 330px; 180 bottom: -9px; 181 } 182 .foot .selected-view .arrow span{ 183 color: #fff; 184 position: absolute; 185 left: 0; 186 bottom: 1px; 187 } 188 #selectedViewList{ 189 padding: 20px; 190 margin-bottom: -20px; 191 } 192 #selectedViewList div{ 193 display: inline-block; 194 position: relative; 195 width: 100px; 196 height: 80px; 197 border: 1px solid #ccc; 198 margin: 10px; 199 } 200 #selectedViewList div span{ 201 display: none; 202 color: #fff; 203 font-size: 12px; 204 position: absolute; 205 top: 0; 206 right: 0; 207 width: 60px; 208 height: 18px; 209 line-height: 18px; 210 text-align: center; 211 background: RGBA(0,0,0,.5); 212 cursor: pointer; 213 } 214 #selectedViewList div:hover span{ 215 display: block; 216 }
js部分:
1)实现商品的全选功能及数量和价格的计算
1 var cartTable = document.getElementById('cartTable'); 2 var tr = cartTable.children[1].rows;//获取table下的tbody下的每一行 3 var checkInputs = document.getElementsByClassName('check'); 4 var checkAllInputs = document.getElementsByClassName('check-all'); 5 var selectedTotal = document.getElementById('selectedTotal'); 6 var priceTotal = document.getElementById('priceTotal'); 7 //计算总数和价格 8 function getTotal(){ 9 var selected = 0; 10 var price = 0; 11 for(var i=0;i < tr.length; i++){ 12 if(tr[i].getElementsByTagName('input')[0].checked){ 13 selected += parseInt(tr[i].getElementsByTagName('input')[1].value); 14 price += parseFloat(tr[i].cells[4].innerHTML);//cells属性为获得tr下面的td 15 } 16 } 17 selectedTotal.innerHTML = selected; 18 priceTotal.innerHTML = price.toFixed(2);//保留两位小数 19 } 20 for(var i=0;i<checkInputs.length;i++){ 21 checkInputs[i].onclick = function(){ 22 if(this.className === 'check-all check'){//如果点击的是全选按钮,则使所有按钮的状态和它相同 23 for(var j=0;j<checkInputs.length;j++){ 24 checkInputs[j].checked = this.checked; 25 } 26 } 27 if(this.checked == false){//如果其中一个变为未选中状态,则使全选按钮取消选中 28 for(var i=0;i<checkAllInputs.length;i++){ 29 checkAllInputs[i].checked = false; 30 } 31 } 32 getTotal(); 33 } 34 }
2)点击已选商品实现商品预览浮层的功能
点击已选商品时会显示出已选择商品的列表
同时在getTotal()函数中增加新创建的div
js代码:
1 function getTotal(){ 2 var selected = 0; 3 var price = 0; 4 var HTMLstr = ''; 5 for(var i=0;i < tr.length; i++){ 6 if(tr[i].getElementsByTagName('input')[0].checked){ 7 tr[i].className = 'on'; 8 selected += parseInt(tr[i].getElementsByTagName('input')[1].value); 9 price += parseFloat(tr[i].cells[4].innerHTML);//cells属性为获得tr下面的td 10 HTMLstr += '<div><img src="'+ tr[i].getElementsByTagName('img')[0].src + '"><span>取消选择</span></div>'; 11 } 12 else{ 13 tr[i].className = ''; 14 } 15 } 16 selectedTotal.innerHTML = selected; 17 priceTotal.innerHTML = price.toFixed(2);//保留两位小数 18 selectedViewList.innerHTML = HTMLstr; 19 if(selected == 0){ 20 foot.className = 'foot'; 21 } 22 } 23 for(var i=0;i<checkInputs.length;i++){ 24 checkInputs[i].onclick = function(){ 25 if(this.className === 'check-all check'){//如果点击的是全选按钮,则使所有按钮的状态和它相同 26 for(var j=0;j<checkInputs.length;j++){ 27 checkInputs[j].checked = this.checked; 28 } 29 } 30 if(this.checked == false){//如果其中一个变为未选中状态,则使全选按钮取消选中 31 for(var i=0;i<checkAllInputs.length;i++){ 32 checkAllInputs[i].checked = false; 33 } 34 } 35 getTotal(); 36 } 37 } 38 39 selected.onclick = function(){ 40 if(foot.className == 'foot'){ 41 if(selectedTotal.innerHTML != 0){ 42 foot.className = 'foot show'; 43 } 44 }else{ 45 foot.className = 'foot'; 46 } 47 }
3)商品列表中的取消选择与事件代理
已选商品列表中没有appendChild的时候div和span都不存在,所以要使用事件代理。
1 selectedViewList.onclick = function(e){ 2 var el = e.srcElement; 3 if(el.className == 'del'){ 4 var index = el.getAttribute('index'); 5 var input = tr[index].getElementsByTagName('input')[0]; 6 input.checked = false; 7 input.onclick(); 8 } 9 }
4)实现增减商品数量及小计价格的计算
1 //增减商品数量事件代理 2 for(var i=0;i<tr.length;i++){ 3 tr[i].onclick = function(e){ 4 e = e|| window.event; 5 var el = e.srcElement; 6 var cls = el.className; 7 var input = this.getElementsByTagName('input')[1]; 8 var val = parseInt(input.value); 9 var reduce = this.getElementsByTagName('span')[1]; 10 switch (cls){ 11 case 'add': 12 input.value = val + 1; 13 reduce.innerHTML = '-'; 14 getsubTotal(this); 15 break; 16 case 'reduce': 17 if(val > 1){ 18 input.value = val - 1; 19 getsubTotal(this); 20 }else{ 21 reduce.innerHTML = ''; 22 } 23 } 24 getTotal(); 25 } 26 tr[i].getElementsByTagName('input')[1].onkeyup = function(){ 27 var val = parseInt(this.value); 28 var tr = this.parentNode.parentNode;//this指的是当前的input,其父节点的父节点就是当前的tr 29 var reduce = tr.getElementsByTagName('span')[1]; 30 if(isNaN(val) || val < 1){ 31 val = 1; 32 } 33 this.value = val;//保证输入框中都是大于1的纯数字 34 if(val <= 1){ 35 reduce.innerHTML = ''; 36 } 37 else{ 38 reduce.innerHTML = '-'; 39 } 40 getsubTotal(tr); 41 getTotal(); 42 } 43 }
5)实现删除商品功能
学会用for循环删除数组中的一些数据时要回置下标 i 。
1 //删除商品 2 deleteAll.onclick = function(){ 3 if(selectedTotal.innerHTML != '0'){ 4 var conf = confirm("确定要删除所选商品吗"); 5 if(conf){ 6 for(var i=0;i<tr.length;i++){ 7 var input = tr[i].getElementsByTagName('input')[0]; 8 if(input.checked){ 9 tr[i].parentNode.removeChild(tr[i]); 10 i --;//因为删除数组中的一个后,后面的索引就会向前移,此时要让i也向前移一个,回置下标i 11 } 12 } 13 getTotal(); 14 } 15 } 16 }
本文来自博客园,作者:小珍珠在河里敲代码,转载请注明原文链接:https://www.cnblogs.com/Jansens520/p/6685733.html