实际需求如下图:
点击文件名,改变大小,状态以及操作的内容,点击删除恢复原装,我们先来分析一下这个需求,以及难点。
- 要求:原生js渲染,所以我们不能用v-for,只能用字符串拼接或者模版字符串来写
- 难点:如何获取到我点击了哪一行元素,我想有很多小伙伴最大的难点就是这个了。
- 如何去改变表格的内容,原生js没有vue那样的机制,数据改变重新渲染
我们针对以上三个方面来写我们的代码
图片需求有四个要素分别是:name,status,size,operate,所以我们的数据要包含这四个字段,我们先来伪造一些数据:
var obj = [
{
name: '你好',
size: 0,
status: 0,
operate: 0
},
{
name: '你好',
size: 0,
status: 0,
operate: 0
}, {
name: '你好',
size: 0,
status: 0,
operate: 0
}, {
name: '你好',
size: 0,
status: 0,
operate: 0
},
]
我们用0和1表示status和操作显示的内容,有了数据那我们就渲染我们的list
首先创建一个<table>
,并给它一个类名tab
,但是给他一个id
会更好
<table class="tab">
</table>
<thead>
<td>名称</td>
<td>大小</td>
<td>状态</td>
<td>操作</td>
</thead>`
for (let i = 0; i < obj.length; i++) {
arr += `
<tbody>
<td class="a"><a href="#" onclick="getIndex(0)">${obj[i].name}</a></td>
<td>${obj[i].size}</td>
<td>${obj[i].status == 0 ? '未下载' : '已下载'}</td>
<td class="b">${obj[i].operate == 0 ? '<span>删除</span>' : '<button onclick="getIndex(1)">删除</button>'}</td>
</tbody>
`
用arr保存,再把arr赋值给tab.innerHTml
,记得要先获取tab
tab = document.getElementsByClassName('tab')
这里要特别说明的是,因为我们给table的是一个class,所以getElementsByClassName
获取到的是个数组,所以我们在赋值的时候应该是tab[0].innerHTML = arr
专业我们的列表就渲染出来了,如图:
到这里我们需要对以上渲染列表进行一个封装,因为原生的js并不会自己重新渲染,所以我们要手动的去做
function rendering() { //渲染函数
arr = `
<thead>
<td>名称</td>
<td>大小</td>
<td>状态</td>
<td>操作</td>
</thead>`
for (let i = 0; i < obj.length; i++) {
arr += `
<tbody>
<td class="a"><a href="#" onclick="getIndex(0)">${obj[i].name}</a></td>
<td>${obj[i].size}</td>
<td>${obj[i].status == 0 ? '未下载' : '已下载'}</td>
<td class="b">${obj[i].operate == 0 ? '<span>删除</span>' : '<button onclick="getIndex(1)">删除</button>'}</td>
</tbody>
`
}
tab[0].innerHTML = arr
}
rendering() // 调用
然后我们封装我们的操作函数
function getIndex(funIndex) {
if (funIndex == 0) {
var list = document.getElementsByClassName('a') // 可根据类名获取具体点击了哪个元素
} else {
var list = document.getElementsByClassName('b') // 可根据类名获取具体点击了哪个元素
}
for (var i = 0; i < list.length; i++) {
list[i].onclick = (function (n) {
return function () {
console.log(n)
if (funIndex == 0) {
obj[n].size = 520
obj[n].status = 1
obj[n].operate = 1
} else {
obj[n].size = 0
obj[n].status = 0
obj[n].operate = 0
}
rendering() // 重新调用
}
})(i)
}
}
这里是根据点击的位置不同分别获取不同的元素,进行不同的操作,然后给所获取到的元素都添加一个方法,当点击这个元素的时候就会把与之对应的索引拿的,然后再去改变对于数据的内容,再次调用渲染函数就行了。