最近呢,知识的输入量比较大,但是呢,依旧是在巩固基础的路上。哈哈哈哈哈哈。大概简单的过了一遍ES5和ES6中新增的数据类型、数组、字符串常用的方法。emmmmm,确实是比较好用。但是,逻辑地实现和代码实现之间是有差距的,今天这个案例,我吧,调试解决问题用了半天,唉,看来还是菜鸟啊,继续加油吧。
案例介绍
+按钮的点击是可以来回切换状态的,在 + — 之间切换。+ 表示添加课程,—表示取消课程。
点击+号,表示选择课程,选中后,选中的课程数和课程会动态渲染在右侧的空白区域。点击过后再次点击时取消选课,渲染数据视图。
最终实现的效果:
案例分析
按钮点击:
需求1:点击按钮,变化按钮的内容以及背景色;
需求2:渲染课程数
需求3:渲染课程到页面
需求1中,使用Map数据类型来存储用户选择的课程,也就是为 + 添加点击事件,点击时把数据压进map中,点击 — 时把数据移出map。需要设置一个属性用来检测按钮是处于 + 还是 — 。
需求2和需求3中,单独写一个渲染的函数来处理页面显示数据的部分。
这就是整个实现的思路,思路捋顺了代码就好写了,我还是用JS4写的,其实更好的写法是可以用ES6的类来实现的,暂时用这个吧,下午我用ES6写完了再放上来。OK,看代码呗。
代码实现
JS:
<script>
// 用来存放选择的课程
var map = new Map();
var lis = document.querySelectorAll("ul>li");
var renderEle = document.querySelector(".renderEle");
// 统计课程
var courseCount = document.getElementById("courseCount");
// 渲染课程数量
function count() {
return [...lis].reduce(function (count, li) {
return count += map.has(li) ? 1 : 0;
}, 0)
}
// 渲染显示选中课程
function renderList() {
return [...lis].filter(function (itemEle) {
return map.has(itemEle); // 返回选择的课程
}).map(function (liEle) {
return `<span>${liEle.querySelector("p").innerHTML}</span>`;
}).join("");
}
// 渲染部分
function run() {
courseCount.innerHTML = `共选择了${count()}门课程`;
renderEle.innerHTML = renderList();
}
// 遍历所有课程列表
lis.forEach(function (item) {
run();
let clickBtn = item.querySelector("a");
// 设置一个属性,检测是否被点击
clickBtn.setAttribute("select", true);
clickBtn.addEventListener("click", function (event) {
// 存在select说明没点击
if (this.getAttribute("select")) {
clickBtn.removeAttribute("select");
map.set(this.parentElement);
this.style.backgroundColor = "red";
this.innerText = "-";
// 点击过后移除属性
} else {
clickBtn.setAttribute("select", true);
map.delete(this.parentElement);
this.style.backgroundColor = "green";
this.innerText = "+";
}
run();
});
console.log(map);
})
console.log(lis);
</script>
面向对象版实现:
window.onload = function () {
// 定义类
class Lensson {
// 构造器:用于获取元素
constructor() {
// 用于存储用户选中的课程
this.map = new WeakMap();
this.lis = document.querySelectorAll("ul>li");
this.countEle = document.getElementById("courseCount")
this.renderEle = document.querySelector(".renderEle");
this.run();
}
run() {
this.render();
this.lis.forEach(ele => {
ele.querySelector("a").addEventListener("click", e => {
// 用于判断按钮的状态
let statue = ele.getAttribute("select"); // 没有
let aBtn = e.target; // 当前点击的元素
// 点击一下 判断是否有select 有说明当前是-
// 所以需要移除课程 点击后的按钮 要变 +
if (statue) {
ele.removeAttribute("select");
this.map.delete(ele);
aBtn.style.backgroundColor = "green";
aBtn.innerHTML = "+";
} else {
// 点击一下 判断是否有select 没有说明当前是+
// 所以需要增加课程 点击后的按钮 要变 -
ele.setAttribute("select", true);
this.map.set(ele);
aBtn.style.backgroundColor = "red";
aBtn.innerHTML = "-";
}
console.log(this.map);
this.render();
})
})
}
count() {
return [...this.lis].reduce((count, li) => {
return (count += this.map.has(li) ? 1 : 0);
}, 0)
}
renderList() {
return [...this.lis]
.filter(itemEle => {
return this.map.has(itemEle); // 返回选择的课程
})
.map(liEle => { // 遍历选中的课程 获得对应的课程名
return `<span>${liEle.querySelector("p").innerHTML}</span>`;
})
.join(""); // 取得字符串
}
render() {
console.log(this.count());
this.countEle.innerHTML = `共选择了${this.count()}门课程`;
this.renderEle.innerHTML = this.renderList();
}
}
new Lensson();
}
html + CSS:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>选课案例</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
height: 100%;
}
.selectClass {
margin: 20px auto;
width: 800px;
height: 200px;
}
.showCourse {
height: 100%;
}
.showCourse span {
display: inline-block;
width: auto;
color: #fff;
border-radius: 5px;
padding: 5px;
background-color: green;
margin: 15px 5px 0;
}
.selectClass>div {
box-sizing: border-box;
float: left;
border: solid 1px #ccc;
width: 400px;
}
.courseName li {
height: 40px;
border: solid 2px rgb(228, 163, 43);
text-align: center;
margin: 15px;
}
.courseName a {
float: right;
width: 20px;
height: 20px;
border-radius: 5px;
background-color: green;
margin-right: 5px;
margin-top: 10px;
line-height: 20px;
color: #fff;
font-size: 20px;
text-decoration: none;
}
.courseName p {
float: left;
margin-left: 10px;
line-height: 40px;
}
</style>
</head>
<body>
<div class="selectClass">
<div class="courseName">
<ul>
<li>
<p>JavaScript</p>
<a href="javascript:;">+</a>
</li>
<li>
<p>CSS</p>
<a href="javascript:;">+</a>
</li>
<li>
<p>HTML</p>
<a href="javascript:;">+</a>
</li>
</ul>
</div>
<div class="showCourse">
<p id="courseCount">共选择了2门课程</p>
<p class="renderEle"></p>
</div>
</div>
</body>
</html>