Babel的作用把不兼容的语法糖编译到兼容的
需要引入babel.js,标签需要增加一个属性
<script type="text/babel">
主要做兼容性
员工列表
最终效果如上图所示。
功能点:1,渲染列表
2,点击后active效果
3,筛选
1,渲染列表
实现方式是先拿到列表的根节点,遍历我们的data,然后用模板字符串进行拼接,拿到一个html字符串,然后使用InnerHtml的方式渲染
/渲染视图
function render(data){
//组装dom结构
let str = '';
data.forEach(item => {
str += `
<tr>
<th>${item.id}</th>
<th>${item.name}</th>
<th>${item.age}</th>
<th>${item.gender}</th>
</tr>
`
});
document.querySelector("#table tbody").innerHTML = str
}
技术点:forEach,字符串拼接,模板字符串,querySelector,innerHtml.
2,我们先拿到第一行所有结点(年龄的),去遍历这些结点,绑定点击事件。点击后的active效果,首先我们在CSS中定义active的效果(.active{color:red}),在遍历中,使用remove方法去删除active属性。然后在单个点击事件的时候,使用this.classList.add("active"),则可增加该属性。
sortAge.forEach((item,key)=>{
item.onclick = function(){
sortAge.forEach((item,key)=>{
item.classList.remove("active")
})
this.classList.add("active")
}
})
其中sortAge,就是我们拿到的年龄哪些按钮的结点
技术点:forEach(可以遍历类数组) 先删除所有的active,然后对想要新增的class增加active.
classList, onclick
3,排序
年龄排序的功能,思路就是我们先拿到所有的年龄按钮的那一行节点,遍历后绑定点击事件,也就是上面样式做的,可以把排序的相关代码写在一起。然后我们会定义一个数组,按照顺序存储年龄,排序的方法。区分是哪个按钮触发了排序,用的是根据数组下标的方式。所以,我们定义数组的时候,是不能随意去改变顺序的。排序的方法,会拿到传入的一个data(全局),然后使用了sort函数,其中形参r1,r2,如果返回r1-r2,则是从小到大,如果返回r2-r1,则是从大到小。默认排序,我们使用id的从小到大排序方式。
let sortArg = [
//年龄从小到大
(data) =>{
data.sort((s1,s2)=>{
return s1.age-s2.age
})
},
//年龄从大到小
(data) =>{
data.sort((s1,s2)=>{
return s2.age-s1.age
})
},
//默认排序
(data) =>{
data.sort((s1,s2)=>{
return s1.id-s2.id
})
},
]
技术点:sort的用法(sort会改变原来的数组,所以可以直接返回),用数组存储方法,并且通过下标来调用。
4,筛选。和前面排序的方式很类似。处理不同的是,筛选使用的方法不同,我们使用了fliter的方法,可以拿到item,key,然后返回item.name==="男"或者“女”的值,注意,filter是不会改变改变data本身的值,但是他的返回值是filter之后,所以我们需要把data重新赋值。
let genderArg = [
(data)=>{
return data.filter((item,key)=>item.gender==="男")
},
(data)=>{
return data.filter((item,key)=>item.gender==="女")
},
(data)=>{
return [...data]
},
]
看代码可以知道,fliter的是返回的值是其fliter后data本身。
5,联动
完成上述步骤,可以实现排序或者筛选,但是会发现,点击排序后,再点击筛选,会失效的问题。对此,我们的做法是,先全局定义两个变量,分别保存排序和筛选的key值,然后再点击排序时,调用筛选的方法(形参为存入的筛选的key),再调用排序。同理点击筛选时,先去调用排序的方法,再筛选。
6,bug
做到这一步貌似做完了,但是仔细测试会发现,反复点击后,比如目前是年龄从大到小,筛选女性的值,然后如果你再点筛选男性,会发现没有值。是因为我们一直在对data进行直接操作(与sort和filter有关)。解决办法是,新在全局存储一个originalData用来保存data的初始状态。然后排序筛选时,不要直接调用data,而是调用OriginalData,可以解决这个问题。
<div class="wrap">
<div class="ctrl">
<div class="age_sort nu">
<a href="javascript:;">年龄从小到大</a>
<a href="javascript:;">年龄从大到小</a>
<a href="javascript:;" class="active">默认排序</a>
</div>
<div class="gender_show">
<a href="javascript:;">只显示男性</a>
<a href="javascript:;">只显示女性</a>
<a href="javascript:;" class="active">默认</a>
</div>
</div>
<table id="table">
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
</tr>
</thead>
<tbody>
<!-- <tr>
<th>0</th>
<th>小明</th>
<th>24</th>
<th>男</th>
</tr> -->
</tbody>
</table>
</div>
<script>
// 数据 对象数组;
let data = [
{
id: 0,
name: '小明',
age: 24,
gender: '男'
},
{
id: 1,
name: '小芳',
age: 30,
gender: '女'
},
{
id: 2,
name: '小美',
age: 31,
gender: '女'
},
{
id: 3,
name: '小刚',
age: 21,
gender: '男'
},
{
id: 4,
name: '小琪',
age: 18,
gender: '女'
}
];
{ //渲染视图
function render(data){
//组装dom结构
let str = '';
data.forEach(item => {
str += `
<tr>
<th>${item.id}</th>
<th>${item.name}</th>
<th>${item.age}</th>
<th>${item.gender}</th>
</tr>
`
});
document.querySelector("#table tbody").innerHTML = str
}
}
let originalData = data
let sortAge = document.querySelectorAll(".age_sort a")
let sortArg = [
//年龄从小到大
(data) =>{
data.sort((s1,s2)=>{
return s1.age-s2.age
})
},
//年龄从大到小
(data) =>{
data.sort((s1,s2)=>{
return s2.age-s1.age
})
},
//默认排序
(data) =>{
data.sort((s1,s2)=>{
return s1.id-s2.id
})
},
]
let ageKey =2;
let genderKey =2;
sortAge.forEach((item,key)=>{
item.onclick = function(){
sortAge.forEach((item,key)=>{
item.classList.remove("active")
})
this.classList.add("active")
data = genderArg[genderKey](originalData)
sortArg[key](data)
ageKey = key
render(data)
}
})
let sortGender = document.querySelectorAll(".gender_show a")
let genderArg = [
(data)=>{
return data.filter((item,key)=>item.gender==="男")
},
(data)=>{
return data.filter((item,key)=>item.gender==="女")
},
(data)=>{
return [...data]
},
]
sortGender.forEach((item,key)=>{
item.onclick =()=>{
sortGender.forEach(item =>{
item.classList.remove("active")
})
item.classList.add("active")
sortArg[ageKey](originalData)
let res = genderArg[key](originalData)
genderKey = key
render(res)
}
})
render(data)