思路
数据驱动思想—-给每个按钮进行绑定点击
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车计算器</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div class="box">
<div class="top" id="top">
<!-- <ul>
<li>
<i class="minus"></i>
<span class="pronum">0</span>
<i class="add"></i>
<span class="info">
单价:12.5元 小计:0元
</span>
</li>
</ul> -->
</div>
<div class="bottom" id="bottom">
<!-- 商品共合计:<span class="pronum num">0</span>件
共花费了:<span class="pronum num">0</span>元 <br><br>
其中最贵的商品单价是<span class="pronum num">0</span>元 -->
</div>
</div>
<script src="js/index.js"></script>
</body>
</html>
CSS
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
.box{
width: 479px;
height: 591px;
margin: 0 auto;
background-image: url(../img/bg1.png);
}
.top{
padding-top:50px;
padding-left: 20px;
height: 387px;
}
/* 减号 */
.minus,.add{
display: inline-block;
width: 52px;
height: 44px;
background-image: url(../img/sub.png);
vertical-align: top;
cursor:pointer;
}
/* 加号 */
.add{
background-image: url(../img/add.png);
}
.pronum,.info{
display: inline-block;
height: 35px;
width: 50px;
background-color: white;
border-radius: 5px;
line-height:35px;
text-align: center;
vertical-align: top; /*基线对齐*/
margin-right: 10px;
}
.info{
background: #171818;
width: 200px;
color:white;
margin-left: 40px;
text-align: left;
padding-left: 20px;
}
.bottom{
padding-top: 20px;
padding-left: 50px;
color:#878787;
}
.num{
vertical-align: middle;
margin-left: 10px;
}
JS
// 1.用AJAX获取数据
// 2.把获取的数据渲染到页面上
// 3.获取元素:绑定点击事件,处理数据
let carModel = (function () {
const getData = function getData() {
let xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "json/data2.json");
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
let data = JSON.parse(xmlHttp.responseText);
render(data);
// sendEle(data); 放在这里 仅仅是getData()执行了一次
}
};
xmlHttp.send();
};
const render = function render(data) {
// data是用来渲染DOM的数据
let top = document.getElementById("top"),
bottom = document.getElementById("bottom");
let total = 0,//一共买啦多少件
totalMoney = 0,//一共花了多少钱
ary = [];//最贵的商品 买过的商品单价
let topStr = '<ul>';
let bottomstr = '';
data.forEach(item => {
let { id, count, price } = item;
total += count;
totalMoney += count * price;//数量*单价
count > 0 ? ary.push(price) : null;//当count大于0 则是买过的
//top数据渲染
topStr += `<li>
<i class="minus" data-id='${id}'></i>
<span class="pronum">${count}</span>
<i class="add" data-id='${id}'></i>
<span class="info">
单价:${price}元 小计:${(count * price).toFixed(2)}元
</span>
</li>`;
});
topStr += '</ul>';
bottomstr += `商品共合计:<span class="pronum num">${total}</span>件
共花费了:<span class="pronum num">${totalMoney.toFixed(2)}</span>元 <br><br>
其中最贵的商品单价是<span class="pronum num">${ary.length > 0 ? Math.max(...ary).toFixed(2) : '0.00'}</span>元`;
top.innerHTML = topStr;
bottom.innerHTML = bottomstr;
sendEle(data);
};
const sendEle = function sendEle(data) {
// let btns=document.querySelectorAll('#top ul li>i');
let btns = document.getElementsByTagName('i');
// [].forEach.call(btns,(item)=>{
// 强制让btns这个类数组使用forEach,通过call改变改变this,来使用
// });
// 类数组转数组的几种办法
// +Array.from(btns) btns转成数组
// +btns=[...btns];//展开运算符
// +btns=[].slice.call(btns) =》相当于btns.slice()
btns = Array.from(btns);
btns.forEach(ele => {
ele.onclick = function () {
// 判断当前元素
let className = this.className;
let id = this.getAttribute('data-id');
data.forEach(item => {
//判断当前的那一行
if (item.id === +id) {
// 用所用item的id和行内获取到的id进行比较 找到我们点击的那个
// 减号
if (className === "minus") {
item.count < 0 ? null : item.count--;
} else {
//加号操作
item.count++;
}
}
})
render(data);
};
});
}
//绑定点击事件
return {
init() {
getData();
}
}
})();
carModel.init();
数据驱动—事件冒泡 跟按钮的父级元素绑定click
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>购物车计算器</title>
<!-- IMPORT CSS -->
<link rel="stylesheet" href="index.css" />
</head>
<body>
<div class="box" id="computedBox">
<!-- <div class="top">
<div class="hang">
<i class="minus"></i>
<span class="pronum">2</span>
<i class="add"></i>
<span class="info">单价:12.5元 小计:0元</span>
</div>
</div>
<div class="bottom">
商品合计:<span class="pronum">0</span> 件
<br>
共花费了:<span class="pronum">0</span> 元
<br>
其中最贵的商品单价是:<span class="pronum">0</span> 元
</div> -->
</div>
<!-- IMPORT JS -->
<script src="index.js"></script>
</body>
</html>
CSS
* {
margin: 0;
padding: 0;
}
.box {
margin: 0 auto;
width: 480px;
height: 590px;
background-image: url(img//bg1.png);
}
/* 按钮 */
.minus,
.add {
width: 52px;
height: 44px;
display: inline-block;
background-image: url(img/sub.png);
vertical-align: middle;
cursor: pointer;
}
.add {
background-image: url(img/add.png);
}
/* 文本框 */
.pronum,
.info {
box-sizing: border-box;
width: 40px;
height: 35px;
line-height: 35px;
background: white;
border-radius: 3px;
text-align: center;
vertical-align: middle;
}
.pronum {
display: inline-block;
}
/* 头部 */
.top {
padding: 50px 20px 0;
height: 387px;
}
.hang {
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.hang .info {
box-sizing: border-box;
padding: 0 10px;
width: 260px;
color: white;
font-size: 14px;
text-align: left;
line-height: 35px;
background: #171818;
}
.bottom {
padding-top: 20px;
color: #878787;
padding-left: 50px;
line-height: 40px;
}
.bottom .num{
width: 80px;
}
js
let computedModel=(function(){
let computedBox=document.querySelector('#computedBox'),
data=null;
// 从服务器获取数据
const queryData=function queryData(){
let xhr=new XMLHttpRequest();
xhr.open("GET","./data.json",false);
xhr.onreadystatechange=function(){
if(xhr.readyState===4&&xhr.status===200){
data=JSON.parse(xhr.responseText);
}
};
xhr.send();
};
//根据数据渲染视图
const render=function render(){
// let str = ``;
// str += `<div class="top">
// ${data.map(item=>{
// return `<div class="hang">
// <i class="minus"></i>
// <span class="pronum">2</span>
// <i class="add"></i>
// <span class="info">单价:12.5元 小计:0元</span>
// </div>`;
// }).join('')}
// </div>`;
let str=`<div class="top">`;
let totalCount=0,
totalPrice=0,
priceArr=[0];
data.forEach(item=>{
let {id,count,price}=item;
totalCount+=count;
totalPrice+=count*price;
if(count>0)priceArr.push(price);
str+=` <div class="hang" data-id="${id}">
<i class="minus"></i>
<span class="pronum">${count}</span>
<i class="add"></i>
<span class="info">
单价:${price}元
小计:${(count*price).toFixed(2)}元
</span>
</div>`;
});
str+=`</div>`;
str+=`<div class="bottom">
商品合计:<span class="pronum ">${totalCount}</span> 件
<br>
共花费了:<span class="pronum num">${totalPrice.toFixed(2)}</span> 元
<br>
其中最贵的商品单价是:<span class="pronum num">${Math.max.apply(null,priceArr).toFixed(2)}</span> 元
</div> `;
computedBox.innerHTML=str;
};
// 点击按钮修改数据
const handle=function handle(){
// 点击computedBox中的任何元素,都会把computedBox的点击事件行为触发
computedBox.onclick=function(ev){
// 获取事件源:具体操作的元素
let target=ev.target;
if(target.tagName==='I'){
// 先找到当前行对应的数据
let id= +target.parentNode.getAttribute('data-id'),
item=data.find(item=>item.id==id);
if(!item) return; //如果没有在数据中找到对应项,后续都不做处理了
if(target.className==="minus"){
item.count--;
if(item.count>0){
item.count=0;
}
render();
return;
}else{
item.count++;
render();
}
// 点击的是加号
};
}
};
return{
init(){
queryData();
render();
handle();
}
};
})();
computedModel.init();