案例:员工列表(es6与原生JS应用)
实现功能
- 根据数据渲染视图
es6应用:
模版字符串、箭头函数、let
思考过程:
- 获取html文档中的需要补充后台数据的容器;
- 解析扁平化处理后的数据(暂时假定后台送达的是扁平化数据),将其装饰上html语句;
- 最终所有填充语句转成字符串赋值给容器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>员工列表</title>
<style>
* {
margin: 0;
padding: 0;
}
body
a{
text-decoration: none;
color: #0d3a4b;
}
.active{
color: #ffffff;
}
.wrap {
width: 700px;
height: 500px;
background-image: url(./images/bg.png);
background-repeat: no-repeat;
margin: 0 auto;
position: relative;
}
.wrap #table {
width: 460px;
border-radius: 12px;
position: absolute;
left: 50%;
top: 160px;
transform: translateX(-50%);
box-sizing: border-box;
overflow: hidden;
}
.wrap #table thead {
width: 100%;
height: 30px;
line-height: 30px;
text-align: center;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
color: #fff;
background: #4cbfe5;
}
.wrap #table thead a {
color: #fff;
}
.wrap #table tbody {
color: #19c2ff;
}
.wrap #table tbody a {
color: #19c2ff;
}
.wrap #table tbody tr {
background: #fff;
}
.ctrl {
position: absolute;
left: 200px;
top: 100px;
}
.ctrl div {
width: 300px;
line-height: 30px;
display: flex;
flex-direction: row;
justify-content: space-around;
}
</style>
</head>
<body>
<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: '女'
}
];
{
let tbody = document.querySelector("#table tbody");
render();
function render(){
let arr = [];
data.forEach((item, index) => {
arr[index] = `<tr>
<th>${item.id}</th>a
<th>${item.name}</th>
<th>${item.age}</th>
<th>${item.gender}</th>
</tr> `;
});
tbody.innerHTML = arr.join("");
}
}
</script>
</body>
</html>
2. 实现筛选和排序
思考过程:
- 筛选和排序两件事需要在一起处理,不能只做一件,否则两类数据不通,通常做法是定义状态。
// 获取两排按钮
let sortBtns = document.querySelectorAll(".age_sort_nu a");
let filterBtns = document.querySelectorAll(".gender_show a");
// 设置默认状态
let sortState = 2;
let genderState = 2;
- 给第一排(排序)和第二排(筛选)按钮添加鼠标点击事件。
- 更新当前点击按钮状态
- 重新根据数据渲染视图
sortBtns.forEach((item, index) => {
item.onclick = ()=> {
sortState = index;
render();
}
});
filterBtns.forEach((item, index) => {
item.onclick = ()=> {
genderState = index;
render();
}
});
- 将筛选、排序功能加入渲染视图render方法
- 利用switch 判断筛选状态,对数据进行过滤
- 利用数组对象的filter方法过滤
- 小编在编码时遇到奇怪的问题,求大神指教!
拷贝代码运行时奇异的问题(求解答) - 注意defalt处理,这里以防用坏原数据,对原数据进行深拷贝(关于深拷贝的坑请看溜_x_i_a_o_迪童鞋总结的知识点:
javascript中数组深拷贝途径及对象数组深拷贝)
- 利用switch 判断排序状态,对数据进行排序
- 利用数组对象的sort方法排序
- 注意关于sort怎样从小到大排还是从大到小排,溜_x_i_a_o_迪童鞋建议大家先任选(n1-n2)、(n2-n1)其中一个,后面log一下,如果错了再换过来就行,没必要死记硬背。
- 利用switch 判断筛选状态,对数据进行过滤
function render(){
let arr = [];
switch (genderState) {
case 0:
arr = data.filter((item) => {
return (item.gender == "男");
});
break;
case 1:
arr = data.filter((item) => {
return (item.gender == "女");
});
break;
default:
arr = new Array(data);
data.forEach((item,index) =>{
arr[index] = {...item};
});
break;
}
switch (sortState) {
case 0:
arr.sort((n1, n2) => {
return (n1.age - n2.age);
});
console.log(arr);
break;
case 1:
arr.sort((n1, n2) => {
return (n2.age - n1.age);
});
break;
default:
break;
}
arr.forEach((item, index) => {
arr[index] = `<tr>
<th>${item.id}</th>
<th>${item.name}</th>
<th>${item.age}</th>
<th>${item.gender}</th>
</tr> `;
});
console.log(arr);
tbody.innerHTML = arr.join("");
}
- 实现按钮高亮切换
- 参数:btns(筛选按钮或排序按钮)、index(当前点击按钮序列)
- 先把“active”类标签(白色样式)全部去除
- 再给当前点击按钮添加“active”类标签
function highlightBtn(btns, index){
btns.forEach(item => {
item.classList.remove("active");
});
btns[index].classList.add("active");
}
- 基本实现了案例要求
- 需补充:在筛选、排序点击事件中调用按钮高亮切换方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>员工列表</title>
<style>
* {
margin: 0;
padding: 0;
}
body
a{
text-decoration: none;
color: #0d3a4b;
}
.active{
color: #ffffff;
}
.wrap {
width: 700px;
height: 500px;
background-image: url(./images/bg.png);
background-repeat: no-repeat;
margin: 0 auto;
position: relative;
}
.wrap #table {
width: 460px;
border-radius: 12px;
position: absolute;
left: 50%;
top: 160px;
transform: translateX(-50%);
box-sizing: border-box;
overflow: hidden;
}
.wrap #table thead {
width: 100%;
height: 30px;
line-height: 30px;
text-align: center;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
color: #fff;
background: #4cbfe5;
}
.wrap #table thead a {
color: #fff;
}
.wrap #table tbody {
color: #19c2ff;
}
.wrap #table tbody a {
color: #19c2ff;
}
.wrap #table tbody tr {
background: #fff;
}
.ctrl {
position: absolute;
left: 200px;
top: 100px;
}
.ctrl div {
width: 300px;
line-height: 30px;
display: flex;
flex-direction: row;
justify-content: space-around;
}
</style>
</head>
<body>
<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: '女'
}
];
{
let tbody = document.querySelector("#table tbody");
let sortBtns = document.querySelectorAll(".age_sort_nu a");
let filterBtns = document.querySelectorAll(".gender_show a");
let sortState = 2;
let genderState = 2;
render();
sortBtns.forEach((item, index) => {
item.onclick = ()=> {
sortState = index;
highlightBtn(sortBtns, index);
render();
}
});
filterBtns.forEach((item, index) => {
item.onclick = ()=> {
genderState = index;
highlightBtn(filterBtns, index);
render();
}
});
function render(){
let arr = [];
switch (genderState) {
case 0:
arr = data.filter((item) => {
return (item.gender == "男");
});
break;
case 1:
arr = data.filter((item) => {
return (item.gender == "女");
});
break;
default:
arr = new Array(data);
data.forEach((item,index) =>{
arr[index] = {...item};
});
break;
}
switch (sortState) {
case 0:
arr.sort((n1, n2) => {
return (n1.age - n2.age);
});
console.log(arr);
break;
case 1:
arr.sort((n1, n2) => {
return (n2.age - n1.age);
});
break;
default:
break;
}
arr.forEach((item, index) => {
arr[index] = `<tr>
<th>${item.id}</th>
<th>${item.name}</th>
<th>${item.age}</th>
<th>${item.gender}</th>
</tr> `;
});
console.log(arr);
tbody.innerHTML = arr.join("");
}
function highlightBtn(btns, index){
btns.forEach(item => {
item.classList.remove("active");
});
btns[index].classList.add("active");
}
}
</script>
</body>
</html>
以上代码是溜_x_i_a_o_迪第一版代码,供初学者参考建议,肯定有许多不合理或者需要改善的地方,小编会再补充完善!