table {
border-collapse: collapse
}
td,
th {
border: 1px solid #ccc
text-align: center
}
input {
text-align: center
width: 20px
outline: none
}
img {
width: 100px
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th><input type="checkbox" id="ckAll">全选</th>
<th>商品名称</th>
<th>商品图片</th>
<th>商品价格</th>
<th>购买数量</th>
<th>小计</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="7" style="text-align: right">
<span>总计:</span>
<span id="total"></span>
</td>
</tr>
</tfoot>
</table>
<script>
let goodses = [{
name: '苹果手机',
img: "https://img12.360buyimg.com/n7/jfs/t1/212335/23/6412/83352/61a99591E098e28c1/03fd3bb84b20d97d.jpg",
price: 300,
count: 2,
isck: false
}, {
name: '华为手机',
img: "https://img11.360buyimg.com/n7/jfs/t1/147090/30/15709/47809/5fbe06d6E0eb8239d/a2e900f693d6e973.jpg",
price: 200,
count: 3,
isck: true
}, {
name: '小米手机',
img: "https://img13.360buyimg.com/n7/jfs/t1/201578/31/15673/77560/619479ceEd1bde507/c0dab826b71e0b84.jpg",
price: 100,
count: 8,
isck: false
}, {
name: '中兴手机',
img: "https://img11.360buyimg.com/n7/jfs/t1/138577/34/21237/197279/61790dbfE7274a47b/569c3d1be96793bd.jpg",
price: 500,
count: 4,
isck: false
}]
// 加载商品信息方法
function loadGoodses() {
goodses.forEach(g =>{
let tr = document.createElement('tr')
// 每个tr里面有7个td
let td1 = document.createElement('td')
let ck = document.createElement('input') //获取里面的输入框
ck.type = 'checkbox' //获取输入框的按钮选项
ck.className = 'ck' //这里只是添加一个标记
// 设置复选框的选中状态
ck.checked = g.isck
// 设置复选框状态发生改变后的事件
ck.onchange = function() {
// 更新商品的状态
g.isck = ck.checked
// 再次调用计算总计的方法
totalPrice()
// 判断是否需要更新全选复选的状态
document.querySelector('#ckAll').checked = goodses.every(r =>r.isck)
}
td1.appendChild(ck) //将获取到的输入框添加到td里面
let td2 = document.createElement('td')
td2.innerHTML = g.name //里面的文本等于数组中商品的name
let td3 = document.createElement('td')
let img = document.createElement('img')
img.src = g.img
td3.appendChild(img)
// td4显示单价
let td4 = document.createElement('td')
td4.innerHTML = '¥' + g.price.toFixed(2)
// td5显示数量
let td5 = document.createElement('td')
let btn1 = document.createElement('button')
btn1.innerHTML = '-'
// 添加减按钮 注册点击事件
btn1.onclick = function() {
g.count--
// 判断商品不能小于1
if (g.count <1) {
g.count = 1
}
// 更新商品数量
count.value = g.count
// 更新小计
td6.innerHTML = '¥' + (g.price * g.count).toFixed(2)
// 更新总计数量,调用函数
totalPrice()
}
td5.appendChild(btn1)
let count = document.createElement('input')
count.value = g.count
td5.appendChild(count)
let btn2 = document.createElement('button')
btn2.innerHTML = '+'
btn2.onclick = function() {
g.count++
// 更新商品数量
count.value = g.count
// 更新小计
td6.innerHTML = '¥' + (g.price * g.count).toFixed(2)
// 更新总计数量,调用函数
totalPrice()
}
td5.appendChild(btn2)
//单个商品的小计
let td6 = document.createElement('td')
td6.innerHTML = '¥' + (g.price * g.count).toFixed(2)
let td7 = document.createElement('td')
let del = document.createElement('button')
del.innerHTML = '删除'
// 添加删除事件
del.onclick = function() {
// 删除tr标签
tr.remove()
// 根据商品的名称获取在数组中的位置
let index = goodses.findIndex(r =>r.name === g.name)
// 根据位置删除对应的商品
goodses.splice(index, 1)
// 更新总价 调用函数
totalPrice()
}
td7.appendChild(del)
// 将所有的td添加到tr中
tr.appendChild(td1)
tr.appendChild(td2)
tr.appendChild(td3)
tr.appendChild(td4)
tr.appendChild(td5)
tr.appendChild(td6)
tr.appendChild(td7)
// 将tr 添加到tbody中
document.querySelector('tbody').appendChild(tr)
})
}
loadGoodses() //调用方法
// 封装计算总金额的方法
function totalPrice() {
// 计算总计
let money = goodses.filter(r =>r.isck).reduce((a, b) =>a + b.count * b.price, 0)
// 显示总计
document.querySelector('#total').innerHTML = '¥' + money.toFixed(2)
}
totalPrice()
// 全选方法
document.querySelector('#ckAll').onchange = function() {
let cks = document.querySelectorAll('.ck')
// 更新DOM
cks.forEach(ck =>{
ck.checked = this.checked
})
// 更新数据
goodses.forEach(g =>{
g.isck = this.checked
})
// 再次调用计算总计的方法
totalPrice()
}
</script>
是。js点击弹出询问框由于没有本地存储,不会调取数据,因此是添加至购物车localstorage。在点击文件链接的时候,弹出询问框是操作系统本身设置好的,任何一个电脑的IE都一样会弹出。关于只有最后一个文本框能触发checknum方法的问题:其实这里有个逻辑错误,主要是<%=i%>中的i是多少的问题。从你贴出来的代码看,你是不是连JS代码也循环输出了吧,也就是有几条购物信息,就会生成几个checknum方法,在JS里,同函数名的方法如果多次定义,则只有最后一个定义的方法有效果,那最后一个checknum方法里的<%=i%>实际就只指代最后一个文本框了。结果就是只有最后一个文本框有效果。
其实楼主只需要循环输出表格,JS代码只用一个就行了,只要在文本框触发JS动作时,把<%i%>作为参数传进JS方法就行了,例如,你可以这么写:
...
<td width="58" height="30"><input name="num<%=i%>" size="5" type="text" value="<%=goodsitem.number%>" onBlur="checknum(this.form,<%=i%>)"></td>
...
把JS方法放到循环外面,这么写:
function checknum(myform,i){
var inp = myform['num'+i]
if(isNaN(inp.value) || inp.value.indexOf('.')!=-1){
alert("请不要输入非法字符!")inp.focus()return}//判断是否为数字值
if(inp.value><%=leave%>){alert("请输入小于现有库存 ("+<%=leave%>+") 的数量!")inp.focus()return}
if(inp.value==0){
alert("请输入大于1的整数!")inp.focus()return}
if(inp.value==""){
alert("请输入修改的数量!")inp.focus()return}
myform.submit()
}
关于数字修改后触发checknum方法的问题:
楼主的checknum方法最后是要提交表单的,所以如果用键盘事件,那每一次输入一个字符或删除一个字符,都会触发表单提交动作,这应该不是楼主要的结果。字符修改后触发JS方法有专门的事件处理方法onchange。楼主可以吧onblur换成onchange试试。