两种方式制作轮播图|青训营笔记

467 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第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方案。