文章目录
参加了这次字节青训营的活动,见到了传说中的月影老师,关键还听他给我们上了两节如何写好JS的课! 太赚啦,今天我把上课学的东西分享出来,和大家一起学习学习!~
月影老师告诉我们写好JavaScript(包括其他语言)的三大原则 ① 各司其责 ② 组件封装 ③ 过程抽象
今天我们来学习写好JavaScript的另一个原则:组件封装
1. 起步
先来看看组件的概念
组件是指Web页面上抽出来一个个包含模版(HTML)、功能(JS)和样式(CSS)的单元。
好的组件具备封装性、正确性、扩展性、复用性。
下面我们来看一个案例——轮播图
2. 轮播图案例
大家在刚接触前端的时候,一定都写过轮播图,还记得如何用原生JavaScript写一个电商网站的轮播图吗?
版本一:API无交互版
结构:HTML
轮播图是⼀个典型的列表结构,我们可以使⽤⽆序列表<ul>
元素来实现。
这里类的命名有点讲究,是一种CSS规则名书命名规范,其中 slider
表示组件名,-list
表示元素,__item
表示具体元素项,--selected
表示的是状态(看完CSS的代码你就知道为什么这样命名更好了~)
<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>
此时的页面,将图片以列表的形式展现出来
表现:CSS
- 使用 CSS 绝对定位将图片重叠在同一个位置
- 轮播图切换的状态使用修饰符(modifier)这里是
--checked
- 轮播图的切换动画使用 CSS transition
再回顾一下这种讲究的CSS规则名命名规范,其中 slider
表示组件名,-list
表示元素,__item
表示具体元素项,--selected
表示的是状态
这样命名,当组件多了,CSS多起来的时候,很容易分辨清楚这段CSS是哪个组件哪个元素哪个状态的样式规则
#my-slider{
position: relative;
width: 790px;
}
.slider-list ul{
list-style-type:none;
position: relative;
padding: 0;
margin: 0;
}
.slider-list__item,
.slider-list__item--selected{
/* 这里使用绝对定位,可以将多张图片重叠在一起,当然要记得给父盒子开相对定位 */
position: absolute;
transition: opacity 1s;
opacity: 0;
text-align: center;
}
.slider-list__item--selected{
transition: opacity 1s;
opacity: 1;
}
最后我们需要通过JavaScript来控制页面的行为
行为:JS —— API
API 设计应保证原子操作,职责单一,满足灵活性。
// 创建一个Slider类,封装一些API
class Slider{
constructor(id){
this.container = document.getElementById(id);
this.items = this.container
.querySelectorAll('.slider-list__item, .slider-list__item--selected');
}
// 获取选中的图片元素:通过选择器`.slider__item--selected`获得被选中的元素
getSelectedItem(){
const selected = this.container
.querySelector('.slider-list__item--selected');
return selected
}
// 获取选中图片的索引值:返回选中的元素在items数组中的位置。
getSelectedItemIndex(){
return Array.from(this.items).indexOf(this.getSelectedItem());
}
// 跳转到指定索引的图片
slideTo(idx){
const selected = this.getSelectedItem();
if(selected){
// 将之前选择的图片标记为普通状态
selected.className = 'slider-list__item';
}
const item = this.items[idx];
if(item){
// 将当前选中的图片标记为选中状态
item.className = 'slider-list__item--selected';
}
}
// 跳转到下一索引的图片:将下一张图片标记为选中状态
slideNext(){
const currentIdx = this.getSelectedItemIndex();
const nextIdx = (currentIdx + 1) % this.items.length;
this.slideTo(nextIdx);
}
// 跳转到上一索引的图片:将上一张图片标记为选中状态
slidePrevious(){
const currentIdx = this.getSelectedItemIndex();
const previousIdx = (this.items.length + currentIdx - 1) % this.items.length;
this.slideTo(previousIdx);
}
}
我们就可以通过手动调用API来使用轮播图了
const slider = new Slider('my-slider');
slider.slideTo(1);
slider.slideTo(2);
slider.slideNext();
slider.slidePrevious();
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HFYIgIVZ-1629954724858)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/315ee5fea47743119b22df6e0107d338~tplv-k3u1fbpfcp-watermark.image)]
或者我们可以直接定义一个定时器,让他自动播放
const slider = new Slider('my-slider');
setInterval(() => {
slider.slideNext();
}, 1000);
版本二 控制流交互版
我们要让用户可以控制我们轮播图的状态,所以需要设计一套控制流
结构 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>
<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>
</div>
表现:CSS
接下来我们来看看CSS样式
通过下面这段代