这是我参与「第四届青训营 」笔记创作活动的第3天。
这三天中,我们一起学习了HTML、CSS和Javascript的相关知识。其中HTML负责结构,CSS负责表现,Js负责行为,在编写程序中,我们应该尽量满足于“各司其责”的原则。结合这两日所学,作者希望通过设计轮播图不同表现方法,来练习:
- 单纯利用HTML和CSS控制表现的改变
- 用原生Js写一个轮播图
同时,比较两种方法之间的优缺点
首先介绍一下,何为轮播图: 轮播图是指在一个模块或者说窗口,通过电脑上鼠标点击、手机上手指滑动后,可以看到多张图片。这些图片就都是轮播图,这个模块就叫做轮播模块。
方法一:单纯利用HTML和CSS实现轮播效果
HTML代码如下:
<div class="loop-wrap" id="loop-wrap">
<div class="loop-images-container">
<img src="images/act1.jpeg" alt="activity_pic" class="loop-image">
<img src="images/act2.png" alt="activity_pic" class="loop-image">
<img src="images/act3.png" alt="activity_pic" class="loop-image">
<img src="images/act4.png" alt="activity_pic" class="loop-image">
<img src="images/act5.png" alt="activity_pic" class="loop-image">
</div>
</div>
CSS代码如下:
.loop-wrap {
position: relative;
width: 1500px;
height: 900px;
margin: 0px auto;
overflow: hidden;
}
.loop-images-container {
position: absolute;
left: 0;
top: 0;
width: 500%;
/* 横向排列 5张图片 宽度应为主容器5倍 */
height: 100%;
font-size: 0;
transform: translate(0, 0); /* 初始位置位移 */
animation: loop 10s linear infinite;
}
.loop-image {
width: 1500px;
height: 900px;
}
这样子就能实现轮播效果了!但是仅仅通过控制CSS表现是有局限性的。主要有几点问题:第一,CSS和HTML需要提前在结构里设定好图片数量,如果前端页面需要更新,如改变图片内容或者数量都要更改底层代码,难于维护;另外,用户不能够自己选择希望看到的图片,如选择下一页等等。这个时候就需要javascript登场了。
方法二:利用Javascript制作轮播图
HTML的结构,一般来讲,轮播图应该是一个典型的列表结构,这里写一个最基本的无序列表ul:
<div id="my-slider" class="slider-list">
<ul>
<li class="slider-list__item--selected">
<img src="example1.png">
</li>
</ul>
</div>
CSS控制表现,这里需要将所有图片重叠在同一位置,轮播图的切换动画使用CSS transition,同时切换状态采用修饰符modifier:
#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;
}
最关键的地方在于Js的部分,由于Js负责行为设计,我们需要考虑两个层面:第一个是API(接口)的设计,第二个是控制流(自定义事件)的设计。从这两个点出发,我们面向slider类,写出如下代码:
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);
}
}
最后,我们应当尽量避免Js直接操作样式,用Class表示状态,纯展示类可以寻求HTML&CSS方案。