从实际例子出发,主要讲的是js不应该去干css做的事情,js主要就是实现交互即可,具体动画应该交给css去做
<div id="main" class="light-on"> /*添加了calss*/`在这里插入代码片`
#main.light-off { /*添加了开关灯的样式*/
background-color: #000;
color: #fff;
}
而JS主要负责单纯的点击事件就好
lightButton.onclick = function(evt) {
if(main.className === 'light-on'){
main.className = 'light-off';
}else{
main.className = 'light-on';
}
}
还可以用纯CSS来实现
<input id="light" type="checkbox"></input> /*CSS中隐藏了*/
<div id="main">
<div class="pic">
<img src="https://p4.ssl.qhimg.com/t01e932bf06236f564f.jpg">
</div>
<div class="content">
<pre>
今天回到家,
煮了点面吃,
一边吃面一边哭,
泪水滴落在碗里,
没有开灯。
</pre>
</div>
<label for="light"> /*for指定ID元素*/
<span id="lightButton"> </span>
<label>
</div>
css
html,body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#light {
display: none;
}
#main {
position: relative;
padding: 20px;
width: 100%;
height: 100%;
background-color: #fff;
color: #000;
transition: all .5s;
}
#light:checked + #main { /*兄弟节点选择器*/
background-color: #000;
color: #fff;
}
.pic {
float: left;
margin-right: 20px;
}
.content {
font-weight: bold;
font-size: 1.5em;
}
#lightButton {
border: none;
width: 25px;
height: 25px;
border-radius: 50%;
position: absolute;
left: 30px;
top: 30px;
cursor: pointer;
background: red;
}
#light:checked+#main #lightButton {
background: green;
}
2. 轮播图设计
- 结构设计
html
<div id="my-slider" class="slider-list">
<ul>
<li class="slider-list__item--selected"> /*选中*/
<img src="https://p5.ssl.qhimg.com/t0119c74624763dd070.png"/>
</li>
<li class="slider-list__item">
<img src="https://p4.ssl.qhimg.com/t01adbe3351db853eb3.jpg"/>
</li>
<li class="slider-list__item">
<img src="https://p2.ssl.qhimg.com/t01645cd5ba0c3b60cb.jpg"/>
</li>
<li class="slider-list__item">
<img src="https://p4.ssl.qhimg.com/t01331ac159b58f5478.jpg"/>
</li>
</ul>
</div>
1)图片结构是一个列表型结构,所以主体用 ul
2)使用 css 绝对定位将图片重叠在同一个位置
3)轮播图切换的状态使用修饰符(modifier)
4)轮播图的切换动画使用 css transition
2. API 设计
getSelectedItem():获得选中的元素
getSelectedItem():获得选中的元素是列表中第几个元素
slide TO() :解决鼠标移动到小圆点时跳转到哪一页
slide Next():鼠标点击跳转到上一页
slide Previous():鼠标点击跳转到下一页
3. 控制流设计
结构设计:
<a class="slide-list__next"></a>
<a class="slide-list__previous"></a>
<div class="slide-list__control">
<span class="slide-list__control-buttons--selected"></span>
<span class="slide-list__control-buttons"></span>
<span class="slide-list__control-buttons"></span>
<span class="slide-list__control-buttons"></span>
</div>
自定义事件
const detail = {index: idx}
const event = new CustomEvent('slide', {bubbles:true, detail})
this.container.dispatchEvent(event)
具体优化有三种优化方式
优化1:插件/依赖注入
避免插件和组件的强耦合,降低耦合度。
比如:不想要小圆点的行为,可以直接把这个插件去掉,修改地方很少,但是还会显示小圆点,只不过失去了交互。
优化2:改进插件/模板化(可维护性大大提升)
HTNL模板化,利于维护。
优化3:组件模型抽象
后续主要讲的是节流和防抖的一些代码实现
Declarative(声明式) v.s. Imperative(指令式)
Imperative(指令式):How to do? 怎么做?
let list = [1, 2, 3, 4];
let map1 = [];
for(let i = 0; i < list.length; i++){
map1.push(list[i] * 2);
}
Declarative(声明式):What to do? 不关心怎么做,关心做什么。
let list = [1, 2, 3, 4];
const double = x => x * 2;
list.map(double);
高阶函数
它们自身输入函数或返回函数,被称为高阶函数
总结
四、总结
如何写好 JavaScript?
- 各司其职:JavaScript 尽量只做状态管理
- 结构、API、控制流分离设计 UI 组件
- 插件和模板化,并抽象出组件模型
- 运用过程抽象的技巧来抽象并优化局部 API