数据:
//数据 data.js文件
let data = [{
id: 1, //任何数据都会有id号
state: true,
img: './images/01.jpg',
name: '牛奶',
price: 5,
count: 2
},
{
id: 2,
state: true,
img: './images/01.jpg',
name: '奶牛',
price: 10,
count: 5
},
{
id: 3,
state: false,
img: './images/01.jpg',
name: '酸奶',
price: 3,
count: 1
}
]
静态结构:
<div class="car">
<table>
<thead>
<tr>
<th><input type="checkbox" id="all" />全选</th>
<th>商品</th>
<th>单价</th>
<th>商品数量</th>
<th>小计</th>
<th>操作</th>
</tr>
</thead>
<tbody id="carBody">
<tr>
<td>
<input class="s_ck" type="checkbox" />
</td>
<td>
<img src="./images/01.jpg" />
<p>黑马键盘</p>
</td>
<td class="price">800¥</td>
<td>
<div class="count-c clearfix">
<button class="reduce">-</button>
<input type="text" value="5" />
<button class="add">+</button>
</div>
</td>
<td class="total">1000¥</td>
<td>
<a href="javascript:" class="del">删除</a>
</td>
</tr>
</tbody>
</table>
<div class="controls clearfix">
<a href="javascript:" class="del-all">删除所选商品</a>
<a href="javascript:" class="clear">清理购物车</a>
<a href="javascript:" class="pay">去结算</a>
<p>
已经选中<span id="totalCount">0</span>件商品;总价:<span id="totalPrice" class="total-price">0¥</span
>
</p>
</div>
</div>
渲染业务的规律:
前提:渲染必须需要 数据 和 静态结构
1.准备数据
2.准备好静态结构
3.数据一般是对象数组(),所以需要遍历拼接
定义一个字符串用于拼接
使用某种循环遍历数据源
拼接字符串,将数据进行替换
4.将拼接生成好的结构渲染到指定位置
// 获取carBody元素
let carBody = document.querySelector('#carBody')
// 封装渲染
let init = function(){
// 数据动态渲染: 数据 +结构 : 遍历 + 拼接 + 赋值
// 定义一个空字符串
let htmlString = ''
// 遍历数据
data.forEach(function(v,i){
// 字符串拼接
htmlString += `<tr>
<td>
<input class="s_ck" type="checkbox" ${v.state?'checked':''} />
</td>
<td>
<img src="${v.img}" />
<p>${v.name}</p>
</td>
<td class="price">${v.price}</td>
<td>
<div class="count-c clearfix">
<button class="reduce" id="${i}">-</button>
<input type="text" value="${v.count}" />
<button class="add" id="${i}">+</button>
</div>
</td>
<td class="total">${v.price * v.count}</td>
<td>
<a href="javascript:" class="del" id="${v.id}">删除</a>
</td>
</tr>`
})
// 赋值
carBody.innerHTML = htmlString
}
//调用封装渲染的函数
init()
事件委托:
1.将事件绑定给已存在的父容器,让子元素进行触发
2.它复用事件冒泡的原理,当子元素触发事件之后,会将事件冒泡给父容器
3.如果想对真正触发事件的元素进行处理,可以使用e.target获取当前真正触发事件的元素
4.如果子元素的操作不一样,需要通过判断,一般我们会对子元素添加一个标识,判断当前触发事件的元素是否有这个标识
使用场景:动态的渲染的元素的事件注册可以使用事件委托,动态渲染的事件的绑定只能使用事件委托
// 加减是动态生成的元素,事件绑定需要使用事件委托
// 事件委托 给父容器添加事件委托, 由子容器冒泡触发事件
carBody.addEventListener('click',function(e){
// 加
if(e.target.className === 'add'){
// 元素操作一定要体现到数据,用户操作是的界面元素,但是本质上操作数据
// 获取单击元素所在对象的索引位置
let i = e.target.id
console.log(i);
// 修改数据
data[i].count++
// 重新渲染
init()
}else if(e.target.className === 'reduce'){
// 减
let i = e.target.id
console.log(i);
// 判断数量是否为1,为1不允许进行减的操作
if( data[i].count == 1){
// 利用return在函数中的特性结束这个if分支语句中return后面代码的运行
return
}
// 修改数据
data[i].count--
// 重新渲染
init()
//删除
}else if(e.target.className === 'del'){
let id = e.target.id
// 删除数据
data.splice('id',1)
// 重新渲染
init()
}
})