基于js、html、css的一个购物车

  1. 本文是参考他人博客修改并添加自我理解的注释的一个文档,其他之处没有太多修改。通过本文让自己明白实现一个项目的思路。感觉这个博主的思路真的很清晰。值得借鉴
  2. html代码:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<link href="css/shop.css" rel="stylesheet" />
		
		<script type="text/javascript" src="js/jquery-1.11.0.js"></script>
	</head>

	<body onselectstart="return false;">
		<template id="temp">
			<tr>
				<td>
					<input type="checkbox" class="check">
				</td>
				<td>
					<img src="./img/{src}">{txt}
				</td>
				<td>{price}</td>
				<td>
					<span class="reduce">-</span><input class="text" value="1"><span class="add">+</span>
				</td>
				<td>{subtotal}</td>
				<td>
					<span class="del">删除</span>
				</td>
			</tr>
		</template>
		<div class="box" id="box">
			<table>
				<thead>
					<tr>
						<th>
							<label>
                    <input type="checkbox" class="checkAll check">全选
                </label>
						</th>
						<th>商品</th>
						<th>单价</th>
						<th>数量</th>
						<th>小计</th>
						<th>操作</th>
					</tr>
				</thead>
				<tbody id="tbody">

				</tbody>
			</table>
			<div class="bottom" id="bottom">
				<aside>

				</aside>
				<label>
            <input type="checkbox" class="checkAll">全选
        </label>
				<span class="delAll">全部删除</span>
				<div>已选商品:
					<span class="selected" id="num">3</span></div>
				<a href="#" class="show">显示或隐藏</a>
				<div>合计:¥
					<span class="total" id="total">7000</span>
				</div>
				<div class="js">结算</div>
			</div>
		</div>
		
		<script type="text/javascript" src="js/shop1.js" ></script>
	</body>

</html>

3.css代码:

body {
	background-color: #bcdecf;
}

div.box {
	width: 700px;
	margin: 50px auto 0;
}

div.box table {
	border-collapse: collapse;
	width: inherit;
	text-align: center;
	background-color: #f6f6f6;
}

div.box table td,
div.box th {
	border: 1px solid #999;
}

div.box th {
	height: 40px;
}

div.box table tbody img {
	height: 50px;
}

div.box table tbody tr span {
	cursor: default;
}

div.box table tbody tr td:nth-child(2) img {
	vertical-align: middle;
}

div.box table tbody tr td:nth-child(4) span {
	display: inline-block;
	width: 15px;
	line-height: 30px;
	background-color: #666;
	color: #eee;
	vertical-align: middle;
}

div.box table tbody tr td:nth-child(4) input {
	width: 20px;
	height: 20px;
	outline: none;
	vertical-align: middle;
	text-align: center;
}

div.box table tbody tr td:nth-child(6) span {
	padding: 4px 10px;
	background-color: #cd4646;
	color: white;
}

div.box div.bottom {
	padding: 15px 0;
	margin-top: 15px;
	height: 25px;
	background-color: white;
	display: flex;
	justify-content: space-between;
	position: relative;
}

div.box div.bottom span.delAll {
	cursor: default;
}

div.box div.bottom div.js {
	padding: 0 6px;
	background-color: #00A5FF;
	color: white;
	margin-right: 10px;
	cursor: default;
}

div.box div.bottom aside div {
	display: inline-block;
}

div.box div.bottom aside div span {
	position: absolute;
	width: 50px;
	line-height: 20px;
	padding: 0 5px;
	background-color: rgba(255, 255, 255, .4);
	color: #333;
	font-size: 10px;
	margin-left: -60px;
	margin-top: 20px;
	transform: rotate(30deg);
	cursor: pointer;
}

div.box div.bottom aside img {
	height: 60px;
	vertical-align: middle;
}

div.box div.bottom aside {
	position: absolute;
	background-color: #0a74cb;
	width: 100%;
	top: -70px;
	padding: 5px;
	box-sizing: border-box;
	display: none;
}

div.box div.bottom aside.on {
	display: block;
}

div.box div.bottom aside:after {
	position: absolute;
	content: "";
	border: 10px solid transparent;
	border-top-color: #0a74cb;
	bottom: -19px;
	right: 280px;
}

div.box div.bottom a,
div.box div.bottom a:visited {
	color: #0b97ff;
	text-decoration: none;
}

js代码:

function $(exp) { //获取元素  #box
	var el;
	
	//对exp匹配以#开头的字符串,且匹配数字、字母、下划线、且以+结尾的字符串,如果存在该匹配,则返回true
	if(/^#\w+$/.test(exp)) {
		el = document.querySelector(exp);
	} else {
		el = document.querySelectorAll(exp);
	}
	return el;
}
var arr = []; /*表单的数据,以数组存储*/
arr[arr.length] = {
	src: '1.jpg',
	txt: 'Casio/卡西欧 EX-TR350',
	price: 5999.88
};
arr[arr.length] = {
	src: '2.jpg',
	txt: 'Canon/佳能 PowerShot SX50 HS',
	price: 3888.50
};
arr[arr.length] = {
	src: '3.jpg',
	txt: 'Sony/索尼 DSC-WX300',
	price: 1428.50
};
arr[arr.length] = {
	src: '4.jpg',
	txt: 'Fujifilm/富士 instax mini 25',
	price: 640.60
};
var temp = $('#temp').innerHTML;
var tbody = $('#tbody');
arr.forEach(function(el) { //把数据插入到HTML中   相当于初始化
	tbody.innerHTML += temp.replace("{src}", el.src).replace("{txt}", el.txt).replace("{price}", el.price)
		.replace("{subtotal}", el.price);
});
var trs = $('#tbody tr');
var box = $('#box');//$():调用上面的函数
var aside = $('#bottom aside')[0];
box.onclick = function(ev) {
	//利用事件冒泡的原理,把事件添加给父级box
//	var oEvent = ev || event; //意思是 ev 成立时 oEvent = event,否则 oEvent = ev
    
	var e = ev || event;
	//打印事件
	console.log("即将打印数据");
	console.log(e);
	
	var target = e.target || e.srcElement; //获取当前点击对象
	var cls = target.className;
	if(cls.indexOf("check") != -1) cls = 'check';
	switch(cls) {
		case 'add': //添加商品数量
			var tr = target.parentNode.parentNode; //找到点击过那一行
			var tds = tr.cells;
			target.previousSibling.value++; //数量那一栏的数字加一
			tds[4].innerText = (tds[2].innerText * target.previousElementSibling.value).toFixed(2);
			//修改小计里面的价格
			break;
		case 'reduce': //减少商品数量
		
		    //target:接受事件作用的DOM节点对象
			var tr = target.parentNode.parentNode; //找到点击过那一行
			
			//tr.cells:返回当前行的所有列<td>
			var tds = tr.cells;
			
			/*target.nextElementSibling.value:为<span>标签后面的<input>标签的值,target.nextElementSibling:当前标签的下一个兄弟标签*/
			if(target.nextElementSibling.value != 1) target.nextElementSibling.value--;
			//数量那一栏减一  tds[4]:即为数量那一栏   tds[2]:单价  target.nextElementSibling.value:数量
			tds[4].innerText = (tds[2].innerText * target.nextElementSibling.value).toFixed(2);
			//修改小计里面的价格
			break;
		case 'text': //直接修改数量那一栏input的值
			var tr = target.parentNode.parentNode;
			var tds = tr.cells;
			target.onblur = function() { //失去焦点时执行
//				this:表示触发当前事件的对象
				tds[4].innerText = (tds[2].innerText * this.value).toFixed(2);
//				this.onblur:对离开当前DOM节点触发的事件进行销毁
				this.onblur = null; //销毁事件
			};
			break;
		case 'del': //删除商品
			var tr = target.parentNode.parentNode;
			if(confirm('你确定要删除吗?'))
				tbody.removeChild(tr);
			break;
		case 'check': //复选框选择商品
			chk(target); //执行复选框函数
			break;
		case 'delAll': //删除全部商品
			if(confirm('你确定要删除吗?'))
				tbody.innerHTML = '';
			break;
		case 'show': //显示、隐藏商品
			aside.classList.toggle('on');
			break;
		case 'cancel':
			var index = target.getAttribute('data-index');
			trs[index].cells[0].children[0].checked = false;
	}
	total(); //计算价格
};
var total_all = $('#total');
var num = $('#num');
total();

function total() { //计算价格
	var sum = 0,
		number = 0;
	trs = $('tbody tr');
	var str = "";
	
	//i为索引,tr为对应 的索引的值
	trs.forEach(
		function(tr, i) {
		//遍历每一行判断,将已选择商品添加到显示隐藏里面
		var tds = tr.cells;
		if(tds[0].children[0].checked) {
			sum += parseFloat(tds[4].innerText);
			number += parseInt(tds[3].children[1].value);
			str += '<div><img src="images/${i+1}.jpg"><span class="cancel" data-index="${i}">取消选择</span></div>';
		}
		total_all.innerText = sum.toFixed(2);
		num.innerText = number;
		aside.innerHTML = str;
	})
}
var checkAll = $('#box .checkAll');//为第一行和最后一行的最左边的复选框

function chk(target) { //复选框判断
	var cls = target.className;
	var flag = true;
	if(cls === 'check') { //点击非全选复选框
		/*当存在一个复选框未选中,全选框为false*/
		for(var i = 0; i < trs.length; i++) {
			
//			var trs = $('#tbody tr'); 获取所有tbody里面的所有行
			
			var checkbox = trs[i].cells[0].children[0];//获取<td>里面的第一个<input>
			if(!checkbox.checked) {  //如果没有被选中
				flag = false;
				break
			}
		}
		checkAll[0].checked = checkAll[1].checked = flag;
	} else { //点击全选复选框,所有复选框的状态保持一致
		for(var i = 0; i < trs.length; i++) {
			var checkbox = trs[i].cells[0].children[0];
			checkbox.checked = target.checked;
		}
		
		//checkAll:为第一行和最后一行的最左边的复选框
		checkAll[0].checked = checkAll[1].checked = target.checked;//从右向左进行赋值
	}
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值