原生js实现购物车的加减与全选,反选功能

效果请看底部图片

html代码




	
		
		购物车
		
	

	

		

全部商品

选择 商品信息 单价 数量 金额 操作
  • Casio/卡西欧 EX-TR350

    580

    - +

    删除

  • Canon/佳能 PowerShot SX50 HS

    380

    - +

    删除

  • Sony/索尼 DSC-WX300

    543

    - +

    删除

全选

已选商品:0

合计:¥0

结算

car.js代码

var data = []; // 数据
var oParent = null, // ul列表盒子
	aChild = null, // 列表项li
	aCheckBtn = null, // 单项产品的选择按钮label
	aProductTitle = null, // 商品名称
	aCost = null, // 单项产品的单价span
	aCountInput = null, // 单项产品的个数input
	aReduce = null, // 单项产品减的按钮
	aAdd = null, // 单项产品加的按钮
	aOneCost = null, // 单项产品的总金额
	aDeletBtn = null; // 单项产品删除按钮

var carFoot = getElementsByClassName(document, 'car-foot-bottom')[0], // 底部盒子
	oAllBtn = getElementsByClassName(carFoot, 'allBtn')[0], // 全选按钮
	oAllNum = getElementsByClassName(carFoot, 'allNum')[0], // 已选商品总件数
	oAllCost = getElementsByClassName(carFoot, 'allCost')[0]; // 已选商品总价格

getEle(); // 获取元素
init(); // 初始化
change(); // 操作

// 获取元素
function getEle() {
	oParent = document.getElementById('car-cont');
	aChild = oParent.children;
	aCheckBtn = getElementsByClassName(oParent, 'checkBtn');
	aProductTitle = getElementsByClassName(oParent, 'productTitle');
	aCost = getElementsByClassName(oParent, 'cost');
	aCountInput = getElementsByClassName(oParent, 'count-input');
	aReduce = getElementsByClassName(oParent, 'reduce');
	aAdd = getElementsByClassName(oParent, 'add');
	aOneCost = getElementsByClassName(oParent, 'oneCost');
	aDeletBtn = getElementsByClassName(oParent, 'deletBtn');
}

// 初始化数据
function init() {
	data = [];
	for(var i = 0; i < aChild.length; i++) {
		var listData = {};
		listData.isCheck = (hasClass(aCheckBtn[i], 'checked') >= 0) ? true : false; // 单个产品是否选中
		listData.title = aProductTitle[i].innerHTML; // 单个商品名
		listData.cost = parseFloat(aCost[i].innerHTML); // 单个产品单价
		listData.num = parseFloat(aCountInput[i].value); // 单个产品个数
		listData.oneCost = listData.cost * listData.num; // 单个产品总金额
		data.push(listData);
	}
	// console.log(data);
	viewFn(); // 渲染视图
}

// 渲染视图
function viewFn() {
	var count = 0; // 计数,计算单项产品选中的个数,当它同总个数相等时,全选也选中。
	var countNum = 0; // 总件数
	var allCostNum = 0; // 总金额

	for(var i = 0; i < aChild.length; i++) {
		aOneCost[i].innerHTML = data[i].oneCost; // 给单项产品添加总金额
		data[i].isCheck ? count++ : count; // 计数,用于是否全选
		// 只有选中的状态下,才计算总件数和总金额
		if(data[i].isCheck) {
			addClass(aChild[i], 'active');
			countNum += data[i].num;
			allCostNum += data[i].oneCost;
		} else {
			removeClass(aChild[i], 'active');
		}
	}
	// 是否全选
	(count === aChild.length && count > 0) ? addClass(oAllBtn, 'checked'): removeClass(oAllBtn, 'checked');
	// 总件数
	oAllNum.innerHTML = countNum;
	// 总金额
	oAllCost.innerHTML = allCostNum;
}

// 操作
function change() {
	// 点击单个按钮改变数据并同时渲染视图
	for(var i = 0; i < aCheckBtn.length; i++) {
		aCheckBtn[i].index = i;
		aCheckBtn[i].onclick = function() {
			if(hasClass(this, 'checked') >= 0) {
				removeClass(this, 'checked');
			} else {
				addClass(this, 'checked');
			}
			init();
		}
	}

	// 全选
	oAllBtn.onclick = function() {
		if(hasClass(this, 'checked') >= 0) {
			removeClass(this, 'checked');
			for(var i = 0; i < aCheckBtn.length; i++) {
				removeClass(aCheckBtn[i], 'checked');
			}
		} else {
			addClass(this, 'checked');
			for(var i = 0; i < aCheckBtn.length; i++) {
				addClass(aCheckBtn[i], 'checked');
			}
		}
		init();
	}

	// 单项商品加
	for(var i = 0; i < aAdd.length; i++) {
		aAdd[i].index = i;
		aAdd[i].onclick = function() {
			data[this.index].num++;
			aCountInput[this.index].value = data[this.index].num;
			init();
		}
	}

	// 单项商品减
	for(var i = 0; i < aReduce.length; i++) {
		aReduce[i].index = i;
		aReduce[i].onclick = function() {
			var n = data[this.index].num;
			n--;
			if(n <= 0) {
				n = 1;
			}
			aCountInput[this.index].value = n;
			init();
		}
	}

	// 更改商品个数的input输入框
	for(var i = 0; i < aCountInput.length; i++) {
		aCountInput[i].index = i;
		aCountInput[i].onchange = function() {
			var value = this.value;
			if(isNaN(value)) {
				alert('请输入数字');
				this.value = 1;
			} else {
				if(this.value < 1) {
					alert('请输入大于等于1的数字');
					this.value = 1;
				} else {
					init();
				}
			}
		}
	}

	for(var i = 0; i < aDeletBtn.length; i++) {
		aDeletBtn[i].index = i;
		aDeletBtn[i].onclick = function() {
			data.splice(this.index, 1);
			oParent.removeChild(aChild[this.index]);

			getEle(); // 获取元素
			init(); // 初始化
			change();
		}
	}
}

base.js代码

// 看obj是否有classname这个class名,没有返回-1,有返回012下标
function hasClass(obj, classname) {
	// 如果这个元素没有class,直接返回
	if(!obj.className) {
		return -1;
	}
	// 如果这个元素有class,则取得所有的class,拆分成数组,遍历,同classname比较,有同名的,则返回下标,否则返回-1
	var classArray = obj.className.split(' ');
	for(var i = 0, len = classArray.length; i < len; i++) {
		if(classArray[i] === classname) {
			return i;
		}
	}
	return -1;
}

// 给某个元素添加class
function addClass(obj, classname) {
	if(!obj.className) {
		// 元素没有class名,则直接添加
		obj.className = classname;
	} else {
		// 元素有class名,则分两种情况,看有没有给定的classname,如果有,则啥也不干,没有才添加
		if(hasClass(obj, classname) === -1) {
			obj.className += ' ' + classname;
		}
	}
}

// 删除某个元素上的class
function removeClass(obj, classname) {
	var index = hasClass(obj, classname);
	if(index !== -1) {
		// 得有这个classname,才删除
		var arr = obj.className.split(' ');
		arr.splice(index, 1);
		obj.className = arr.join(' ');
	}
}

// 通过classname获取元素,返回元素集合
function getElementsByClassName(parent, classname) {
	var arr = [];
	var elems = parent.getElementsByTagName("*");
	for(var i = 0, len = elems.length; i < len; i++) {
		if(hasClass(elems[i], classname) !== -1) {
			arr.push(elems[i]);
		}
	}
	return arr;
}

css样式

*{
	padding: 0;
	margin: 0;
	list-style: none;
	font-family: 'Hiragino Sans GB','Lantinghei SC','Microsoft Yahei',SimSun;
}
#wrap{
	width:990px;
	margin:10px auto 0;
}
#wrap h4{
	width:100%;
	color:#f40;
	font-size:16px;
	padding:10px 0;
	border-bottom:2px solid #e6e6e6;
}
#wrap h4 span{
	display:inline-block;
	position:relative;
}
#wrap h4 span:after{
	content:'';
	position:absolute;
	height:2px;
	background:#f40;
	width:100%;
	left:0;
	bottom:-12px;
}


/*title*/
.car-title{
	width:100%;
	overflow:hidden;
	font-size:0;
}
.car-title p,.car-title span{
	display:inline-block;
	font-size:16px;
	line-height:50px;
	height:50px;
}
.car-title span:nth-child(1){
	padding-left:10px;
	width:80px;
}
.car-title span:nth-child(2){
	padding-left:91px;
	width:302px;
}
.car-title span:nth-child(3){
	padding-left:110px;
}
.car-title span:nth-child(4),.car-title span:nth-child(5),.car-title span:nth-child(6){
	padding-left:80px;
}

/*全选按钮*/
.allBtn{
	width:80px;
	height:50px;
	cursor:pointer;
}
.allBtn label,.checkBtn{
	width:16px;
	height:14px;
	background-image:url(../img/icon.png);
	background-position:0 0;
	display:inline-block;
	cursor:pointer;
}
.allBtn.checked label,.checkBtn.checked{
	background-position:0 -20px;
}

/*car-cont*/
.car-cont{
	width:988px;
}
.car-cont li{
	height:107px;
	border:1px solid #ccc;
	margin-bottom:10px;
	overflow:hidden;
}
.car-cont li.active{
	background:#fff8e1;
}
.car-cont li p{
	overflow:hidden;
	float:left;
}
.car-cont li p:nth-child(1){
	width:108px;
}
.car-cont li p:nth-child(1) label{
	margin:15px 0 0 15px;
}
.car-cont li p:nth-child(2){
	width:428px;
}
.car-cont li p:nth-child(2) img{
	width:80px;
	height:80px;
	border:1px solid #eee;
	float:left;
	margin-top:13px;
}
.car-cont li p:nth-child(2) span{
	float:left;
	width:187px;
	padding:30px 0 0 15px;
}
.car-cont li p:nth-child(3),.car-cont li p:nth-child(5){
	line-height:107px;
	width:130px;
	text-align:center;
}
.car-cont li p:nth-child(5){
	color:#f40;
	width:152px;
}
.count {
    width: 90px;
    padding-top:42px;
}
.count .add, .count input, .count .reduce {
    float: left;
    margin-right: -1px;
    position: relative;
    z-index: 0;
}
.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;
    z-index: 3;
    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;
    z-index: 2;
}
.car-cont li p:nth-child(6){
	float:right;
	padding: 0 35px 0 10px;
}
.car-cont li p:nth-child(6) em{
	font-size:16px;
	font-style:normal;
	line-height:107px;
	cursor:pointer;
}
.car-cont li p:nth-child(6) em:hover{
	color:#f40;
	text-decoration: underline;
}

/*底部*/
.car-foot{
	width:990px;
	height:50px;
	position:relative;
	z-index:100;
}
.car-foot-bottom{
	width:990px;
	height:50px;
	background:#e5e5e5;
	overflow:hidden;
}
.car-foot p{
	float:left;
	height:50px;
	line-height:50px;
}
.car-foot p:nth-child(1){
	padding-left:8px;
}
.car-foot p:nth-child(3){
	margin-left:400px;
	cursor:pointer;
}
.car-foot p:nth-child(4){
	padding-left:100px;
}
.car-foot p em{
	font-style:normal;
	color:#f40;
	font-weight:bold;
	font-size:20px;
}
#submitBtn{
	float:right;
	width:120px;
	height:50px;
	line-height:50px;
	color:#fff;
	font-size:16px;
	text-align:center;
	background:#f40;
	cursor:pointer;
}

原生js实现购物车的加减与全选,反选功能_第1张图片

你可能感兴趣的:(购物车,购物车,全选反选,js原生)