这是我参与「第四届青训营 」笔记创作活动的第7天
这节课的三要点 之二
组件封装
好的UI组件具备正确性、扩展性、复用性。
这个我也是知道的,自己的理解是:就好像js里的函数,可以复用的函数可以封装,便于维护,修改,拓展复用。
接着月影老师放出了另一个常见的小例子,电商网站的轮播图。
之前也有写过,但是似乎忘了点
那就趁着这个机会,在复习一遍吧
先看代码
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>
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;
}
首先html这个界面还好说,用的无序列表 ul & li 并放上图片。
css样式 不难看出,先用定位把4张图放在一个位置,再用用一个类名 selected 来控制某张图片的显示。
小注意点:在这之前先把所有的类名设置成原始样式,在把单独设有selected的展现出来。
接下来是js
class Slider{
constructor(id){
this.container = document.getElementById(id);
this.items = this.container
.querySelectorAll('.slider-list__item, .slider-list__item--selected');
}
getSelectedItem(){
const selected = this.container
.querySelector('.slider-list__item--selected');
return selected
}
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);
}
}
const slider = new Slider('my-slider');
slider.slideTo(3);
setInterval(()=>{
slider.slideNext();
},5000)
首先我想说的是,果然很 高级 直接用的class,我记得当时我练习写轮播图时,还是不会这么注意的,看来这种组件封装还是看起来最舒服的。
那就让我先一步步把他读懂吧:
首先
class Slider{
constructor(id){
this.container = document.getElementById(id);
this.items = this.container
.querySelectorAll('.slider-list__item, .slider-list__item--selected');
}
用class定义了一个类名Slider
用到了constructor原型对象
所以,当我们 new 一个实例对象时,新创建的实例对象 里面的this会指向这个实例对象
我们直接看到这段代码的后段部分会发现
const slider = new Slider('my-slider');
这里说明已经有了一个slider的对象 并且传递了参数 'my-slider'
这里的 'my-slider' 传递给到了上面class里 constructor 的 id 里
所以我们就直接带入去看class构造函数吧
1.拿到了id为 'my-slider' 的div盒子 用container保存
2.拿到id为 'my-slider' 的类名下所有类名为 .slider-list__item, .slider-list__item--selected 即所有图片的类名
接着:
getSelectedItem(){
const selected = this.container
.querySelector('.slider-list__item--selected');
return selected
}
定义方法getSelectedItem():这个方法最终是返回一个被展示的选定的图片标签
getSelectedItemIndex(){
return Array.from(this.items).indexOf(this.getSelectedItem());
}
定义方法getSelectedItemIndex(): 返回被展示的标签索引
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';
}
}
定义方法slideTo(idx):跳转到指定索引图片
传入一个参数idx即索引,若使用此方法,将会使传入的索引那个对应的图片拿到展示出来的类名 即 'slider-list__item--selected'
slideNext(){
const currentIdx = this.getSelectedItemIndex();
const nextIdx = (currentIdx + 1) % this.items.length;
this.slideTo(nextIdx);
}
定义方法slideNext():跳转下一张图片
首先,拿到此刻被选中的标签的索引
其次,让此索引+1,并且➗4(即此轮播图的图片数),为了防止当轮播图到最后一张时此时3+1变成了4但是我们没有索引为4的图片,总共只有0 1 2 3
最后使用this.slideTo(nextIdx)跳转到计算好的下一张图片
slidePrevious(){
const currentIdx = this.getSelectedItemIndex();
const previousIdx = (this.items.length + currentIdx - 1)
% this.items.length;
this.slideTo(previousIdx);
}
定义方法slidePrevious():跳转到上一张图片
总觉得方法好复杂,我觉得这样写比较好:
slidePrevious(){
const currentIdx = this.getSelectedItemIndex();
const previousIdx = currentIdx===0?3:currentIdx-1;
this.slideTo(previousIdx);
}
就像是上面的下一张图片一样可以用三元表达式
slideNext(){
const currentIdx = this.getSelectedItemIndex();
const nextIdx = currentIdx===3?0:currentIdx+1;
this.slideTo(nextIdx);
}
这些就是最基本的功能,接下来就是定义按钮和原点了
这样子看来确实整齐的多,想当初自己练习写轮播图很乱....
好了今天先写到这里,明天继续深入!