js版的模拟购物车
心路过程过于复杂,已经三天没睡好啦。????????????
模拟购物车分为好几大模块,做完已经佛了。
1. 模拟一个后台数据Data,用json的数组对象。
2. 动态创建Dom 元素和添加事件,这一块是核心部分。
????(1)动态创建dom元素,主要使用createElement和appendChild两种属性,构成一个基本的购物车模型。
????(2)给全选/反选添加点击事件:获取全选文本框,灵活使用input的checked属性,点击时,对应Date数据中的复选框被选中,同时这一行的背景为淡粉色,否则为白色。
????(3)复选框的单个事件:点击时,复选框被选中,同时这一行的背景为淡粉色,否则为白色。另外,当没有选择任何一个单选框时全选框取消事件(cheaked=false).
????(4)加减商品个数的事件:给加减(+ -)按钮添加点击事件,点击 + 时,对应的商品个数加1,点击 - 时,对应的商品个数减1。
????(5)输入数字的文本框事件:输入的值就等于当前Data索引值中的商品个数numgoods.Data[this.index].num = this.value;
????(6)小计事件:每件商品的小计都等于商品的单价乘以数量。注:要给加减商品个数,输入数字文本框事件里添加该事件,在改变商品数目时,小计的值也会跟着变化。
????(7)合计事件:当选择了商品前面的复选框时,自动将商品的小计加在一起。注:给所有的事件都添加合计事件,一旦改变任何事件,商品合计的值都会改变。
注意:this关键字很常见,但是它似乎变幻莫测,让人抓狂
一、方法调用模式????
当函数被保存为一个对象的属性时,它就可称为这个对象的方法。当一个方法被调用时,this被绑定到这个对象上。如果调用表达式包含一个提取属性的动作(. 或 [ ]),那么它被称为方法调用。
var name = "window";
var obj = {
name: "kxy",
sayName: function() {
console.log(this.name);
}
};
obj.sayName(); //kxy
二、函数调用模式????
当一个函数并非一个对象的属性时,那么它就是被当做函数来调用的。在此种模式下,this被绑定为全局对象,在浏览器环境下就是window对象
var name = "window";
function sayName() {
console.log(this.name);
}
sayName();
三、构造函数模式????
如果在一个函数前面加上new关键字来调用,那么就会创建一个连接到该函数的prototype成员的新对象,同时,this会被绑定到这个新对象上。这种情况下,这个函数就可以成为此对象的构造函数。例如
function Obj() {
this.name = "kxy";
}
var person = new Obj();
console.log(person.name); //kxy
Obj作为构造函数被调用,函数体内的this被绑定为新创建的对象person。
????????????????????????????????????????????????????????????????????????????
进入正题啦。。。。。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>淘宝购物车</title>
<style>
*{
padding:0;
margin:0;
}
button{
background: #fad3ff;
outline: none;
}
.car{
position: relative;
width:1000px;
height:600px;
border: 1px solid black;
margin:auto;
}
.cartitle {
width:100%;
height:50px;
/*border:1px solid gainsboro;*/
background: #fff2f6;
display: flex;
flex-direction: row;
text-align: center;
color: #0016a1;
}
.cartitle>div{
flex: 1;
font-size: 15px;
line-height:50px;
}
.car_goods{
display: flex;
flex-direction: row;
flex:1;
border-bottom: 1px dashed #bb6d63;
}
.car_goods>div{
flex:1;
text-align: center;
height: 70px;
line-height: 70px;
}
.imgae{
width:50px;
vertical-align: middle;
}
.l_btn,.r_btn{
width:25px;
outline: none;
}
.write_num{
width:23px;
text-align: center;
outline: none;
}
.footer{
position: absolute;
bottom:0;
width:100%;
height:70px;
background: #e7e7fb;
display: flex;
flex-direction: row;
flex:1;
}
.totprice{
flex:0.7;
font-size: 20px;
line-height: 70px;
margin-left:15px;
color: #ff0000;
}
.spend{
background: red;
color:#fff;
font-size: 23px;
text-align: center;
line-height: 70px;
flex:0.3;
}
.bgcolor{
background: #fbbff8;
}
</style>
</head>
<body>
<div class="car">
<div class="cartitle">
<div><input id="all_check" type="checkbox"/>全选/反选</div>
<div>商品名称</div>
<div>图片</div>
<div>单价</div>
<div>数量</div>
<div>小计</div>
<div>删除</div>
</div>
<div class="carlist">
</div>
<div class="footer">
<div class="totprice">
合计:<span id="allprice">0</span>¥
</div>
<div class="spend">去结算</div>
</div>
</div>
<script>
//模拟一个后台数据
var data=[
{
name:"凉鞋",
img:"./img/1.jpg",
price:65,
num:1,
small_tot:65
},
{
name:"连衣裙",
img:"./img/2.jpg",
price:50,
num:1,
small_tot:50
},
{
name:"口红",
img:"./img/3.jpg",
price:19,
num:1,
small_tot:19
},
{
name:"手链",
img:"./img/4.jpg",
price:48,
num:1,
small_tot:48
}
];
//动态创建dom元素
var goods= {
Data: data,
list: document.getElementsByClassName("carlist")[0],
allcheck: document.getElementById("all_check"), //获取全选框
//创建dom元素
Creat: function () {
for (var i = 0; i < this.Data.length; i++) {
var goods_list = document.createElement("div");
goods_list.className = "car_goods";
//追加商品前面的选择框
var select = document.createElement("div");
goods_list.appendChild(select);
var put1 = document.createElement("input");
put1.type = "checkbox";
put1.className = "sel_put";
//给每个单选框添加点击事件
put1.index=i;
put1.addEventListener("click",this.Check_one);
select.appendChild(put1);
for (var key in this.Data[i]) {
var everele = document.createElement("div");
if (key == "img") {
var img = document.createElement("img");
img.className = "imgae";
img.src = this.Data[i][key];
everele.appendChild(img);
}
else if (key == "num") {
var leftbtn = document.createElement("button");
leftbtn.index=i;
leftbtn.className = "l_btn";
leftbtn.innerHTML = "-";
leftbtn.addEventListener("click",this.Add_minus);
everele.appendChild(leftbtn);
var write = document.createElement("input");
write.index=i;
write.className = "write_num";
write.value = this.Data[i][key];
write.addEventListener ("keyup",this.Input_thing);
everele.appendChild(write);
var rightbtn = document.createElement("button");
rightbtn.index=i;
rightbtn.className = "r_btn";
rightbtn.innerHTML = "+";
rightbtn.addEventListener ("click" , this.Add_minus);
everele.appendChild(rightbtn);
}
else if (key == "price" || key == "small_tot") {
everele.className = key;
everele.innerHTML = this.Data[i][key] + "¥";
}
else {
everele.innerHTML = this.Data[i][key];
}
goods_list.appendChild(everele);
}
//管理栏 删除功能
var manger = document.createElement("div");
goods_list.appendChild(manger);
var put2 = document.createElement("button");
put2.className = "del";
put2.innerHTML = "删除";
manger.appendChild(put2);
this.list.appendChild(goods_list);
}
},
//全选和反选事件
Allcheck: function () {
var cargoods = document.getElementsByClassName("car_goods");
// console.log(this); this指的goods对象
this.allcheck.onclick = function () {
var select_kung = document.getElementsByClassName("sel_put");
for (var i = 0; i < select_kung.length; i++){
// checked 属性设置或返回 checkbox 是否应被选中。
select_kung[i].checked =!select_kung[i].checked ;
if(select_kung[i].checked ){
cargoods[i].style.background ="pink";
// cargoods[i].className ="car_goods bgcolor";
}
else{
cargoods[i].style.background ="white";
// cargoods[i].className ="car_goods";
}
}
goods.Totle_price();
}
},
//复选框的单个事件
Check_one:function(){
var cargoods = document.getElementsByClassName("car_goods");
// console.log(this.index);//this 指的是每个单选框事件input(集合) this.index:0,1.2,3
if(this.checked){
cargoods[this.index].style.background ="pink";
}
else{
cargoods[this.index].style.background ="white";
}
goods.Totle_price();
//没有一个单选时,全选取消
var put1=document.getElementsByClassName ("sel_put");
for(var i=0;i<put1.length;i++){
if(put1[i].checked ){
return;
}
}
goods.allcheck.checked =false ;
},
//点击加减时的事件
Add_minus:function(){
var writenum=document.getElementsByClassName ("write_num");
var writevalue= writenum[this.index].value ; //this 指的是商品数量(集合) this.index 表示其索引值。
if(this.className == "l_btn"){
// writevalue--;
if(writevalue>1){
writevalue--;
}
}
else if(this.className =="r_btn"){
writevalue ++;
}
writenum[this.index].value=writevalue ;
goods.Data[this.index].num=writevalue ;
goods.Small_tot ( this.index);
goods.Totle_price();
},
//文本框输入事件
Input_thing:function() {
if(this.value>0) { //this 指的是输入文本框
goods.Data[this.index].num = this.value;
}
goods.Small_tot ( this.index);
goods.Totle_price();
},
//小计价格
Small_tot:function (index){
var smalltot=document.getElementsByClassName ("small_tot")[index];
goods.Data[index].small_tot= goods.Data[index].price*this.Data[index].num;
smalltot.innerHTML =this.Data[index].small_tot+"¥";
},
//合计事件
Totle_price: function(){
var put1=document.getElementsByClassName ("sel_put");
var all_tot=0;
for(var k=0;k<goods.Data.length;k++){
if(put1[k].checked ){
all_tot +=goods.Data[k].small_tot ;
}
}
// var allprice=document.getElementById("allprice");
// allprice.innerHTML =all_tot ;
document.querySelector("#allprice").innerHTML =all_tot ;
}
};
//调用枚举对象
goods.Creat ();
goods.Allcheck ();
</script>
</body>
</html>
????????????????????????????煎熬的一天结束了。