效果图:css此处自行设计。

html:
<div class="box" id="ComputedBox">
<div class="top">
<div class="hang">
<!-- i标签显示斜体文本效果。minus和add是自定义类名,用于控制按钮的样式。-->
<i class="minus"> </i>
<span class="pronum">2</span>
<i class="add"> </i>
<span class="info">
单价:12.5元
小计:<em>0</em>元
</span>
</div>
</div>
<!-- 底部显示商品合计件数和总价 -->
<div class="bottom">
商品合计:<span class="pronum">0</span> 件
<br>
共花费了:<span class="pronum">0</span> 元
</div>
</div>
取出数据:
// 想操作哪些DOM,就要先获取这些元素
let computedBox = document.querySelector('#computedBox'),
// 获取整个计算器元素,document.querySelector可以获取文档中的第一个匹配的元素。
topBox = computedBox.querySelectorAll('.top'),
// 获取顶部元素,querySelectorAll可以获取文档中所有top元素的集合。
[totolCountBox,totolPriceBox] = Array.from(computedBox.querySelectorAll('.bottom span')),
// 获取底部盒子元素并用array.from将其转换为商品合计和总计元素的数组。
// Array.from() 是 ES6 中新增方法,它可以从类数组对象或可迭代对象(如字符串、Set、Map、NodeList 等)创建一个新的数组实例。
countsBox=[],
subtotalBox=[];
// 定义数组,用于存储各项商品的数量和小计。
取出dom元素以后,我们就可以进行动态绑定啦:
// 具名函数表达式binding()
// 在JavaScript中,具名函数表达式允许在函数表达式中给函数本身命名,而不是仅仅将函数赋值给一个变量。
const binding = function binding() {
let str='';
// 定义一个字符串变量,用于存储商品信息。
data.forEach(item,index => {
// forEach 用于遍历data数组,获取每一项商品的数量和价格。
let {count,price} = item;
// 解构赋值,获取每一项商品的数量和价格。
str += `<div class="hang">
<i class="minus"></i>
<span class="pronum">${count}</span>
<i class="add"></i>
<span class="info">
单价:${price}元
小计:<em>${count*price}</em>元
</span>
</div> `;
// 新增每一项商品的HTML代码。
});
topBox.innerHTML = str;
// 将当前商品信息填充到顶部元素中。
countsBox = Array.from(topBox.querySelectorAll('span.pronum'));
// 把底部数据元素转换为数组,用于计算商品个数和总费用。
subtotalBox = Array.from(topBox.querySelectorAll('em'));
// 得到每项商品的小计元素的集合,用于计算总费用。
};
binding();
// 调用binding()函数,初始化计算器。
动态绑定后便可以计算总计信息:
const computed = function computed() {
let counts = 0;
prices = 0;
// 定义两个变量,用于存储商品的数量和价格。
countsBox.forEach(_,index => {
// forEach 遍历商品数量元素,获取每一项商品的数量。
// +bindBox[index].innerHTML 将字符串转换为数字。或者用Number()函数也行。
counts += +countsBox[index].innerHTML;
// 累加商品数量得到总数量。
prices += +subtotalBox[index].innerHTML;
// 累加商品小计得到总费用。
});
totolCountBox.innerHTML = counts;
// 更新商品总数。
totolPriceBox.innerHTML = prices;
// 更新商品总费用。
};
// 定义计算器函数。
此时可以修改绑定函数:
subtotalBox = Array.from(topBox.querySelectorAll('em'));
// 得到每项商品的小计元素的集合,用于计算总费用。
computed();
// 计算一下总费用。
};
binding();
函数也写好,我们就可以基于事件委托实现点击事件绑定啦:
注意:在元素上写事件和addEventListener()的区别?
- onclick添加事件不能绑定多个事件,后面绑定的会覆盖前面的。而addEventListener能添加多个事件绑定,按顺序执行。
- onclick只能冒泡,addEventListener()可以得到捕获or冒泡。
- addEventListener方式,不支持低版本的IE。(attachEvent 支持IE)。
- 普通方式绑定事件后,不可以取消。addEventListener绑定后则可以用 removeEvenListener 取消。
topBox.addEventListener ('click',function(ev) {
// addEventListener() 方法用于向指定元素添加一个或多个事件监听器。
// 监听顶部元素的点击事件。
let target = ev.target;
targetTag= target.tagName;
// 获取点击的元素的标签名。
targetSty = target.className;
// 获取点击的元素的类名。
if(targetTag !== 'I' )return;
// 如果点击的不是i标签,即不是加号或减号,则直接返回。
let parent = target.parentNode;
index = +parent.getAttribute('index');
// 获取点击的元素的索引值。
price = data[index].price,
itemCountBox = countsBox[index],
itemSubtotalBox = subtotalBox[index];
// 获取当前点击的商品的价格和数量元素。
if(targetSty ==='minus'){
// 如果点击的是减号,则减少商品数量。
itemCountBox.innerHTML--;
if(+itemCountBox.innerHTML < 0){
itemCountBox.innerHTML = 0;
}
}else{
itemCountBox.innerHTML++;
}
itemSubtotalBox.innerHTML = itemCountBox.innerHTML;
// 更新商品数量。
computed();
// 计算总费用。
});
// 监听顶部元素的点击事件,并执行相应的操作。
在此补充一点:es6箭头函数。
// 箭头函数,单个元素括号可省略
let fn = (name) => {
// 函数体
return `Hello ${name} !`;
};
// 等同于
let fn = function (name) {
// 函数体
return `Hello ${name} !`;
};
详细链接:ES6箭头函数详解-优快云博客
完结撒花~~
485

被折叠的 条评论
为什么被折叠?



