手撕轮播图
1.普通写法(上面代码的手撕)
-
HTML
不用过多解释,就是创建了一个确定了id,class的div。(id用于识别 class用于样式)
在div里写了一个ul,ul里面写了4个li,每个li都有一个class,用于确定是否选中。而且只能有一个选中的。
在每个li里放一张照片,一共放了四张。
- class = "slider-list__item--selected" 的代表选中
- class = "slider-list__item" 的代表未选中
<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的代码用了类选择器,id选择器,并且里面写了很多declaration。正好复习一下昨天学到的。
来对每一行代码都进行一个详细的解释。
#my-slider{ /* id选择器 给id="my-slider"的元素设置样式 也就是最外层的div*/ position: relative; /* 容器相对定位,内部的绝对定位元素可以相对于它进行定位*/ width: 790px;/* 设置宽度 */ } .slider-list ul{ /* [类选择器 标签选择器] 这是一个后代组合。类选择器选中了div元素,div元素的后代中所有的ul被选中 所以这一行就是给div以及其后代中的ul元素设置样式*/ list-style-type:none;/* 由于每一个li都有一个小圆点,我们肯定不需要,所以这一行可以进行移除 */ position: relative; /* 是为了让内部的绝对定位元素( .slider-list__item 和 .slider-list__item--selected)能够相对于该 ul 进行定位。 */ padding: 0; /* 内边距为0 即去除内边距 */ margin: 0; /* 外边距为0 即去除外边距 */ } .slider-list__item, .slider-list__item--selected{/* 这两行是用逗号连接的,意思是给class为.slider-list__item和.slider-list__item--selected的元素一起设置样式 */ position: absolute; /* 表示这些元素将被从文档流中移除,并根据最近的定位父元素来进行定位。 因为 .slider-list 的父容器 #my-slider 是相对定位的,所以它内部的 .slider-list__item 和 .slider-list__item--selected 会相对于 #my-slider 来定位。 */ transition: opacity 1s; /* 确保在图片切换时有平滑的过渡效果。 */ opacity: 0;/* 初始时透明度为0 也就是所有照片都隐藏 */ text-align: center;/* 图片在li中居中 */ } .slider-list__item--selected{ /* 为class为slider-list__item--selected的元素单独设置样式 */ transition: opacity 1s;/* 过渡效果,切换的时候改变透明度并持续1秒 */ opacity: 1;/* 透明度设置成1 也就是显示照片 */ }
-
JS文件我们采用手写的方式,把每一个函数都弄明白其中的意思。
想要实现轮播图,就需要进行图片的切换。当前选中哪张图片,切换到下一张照片,切换到上一张照片。这些是目前需要实现的三个功能。
-
定义一个类Slider,类里有一个构造函数,我们给一个参数id。用来指定哪个元素是Slider类。
然后就需要进行元素的获取,document.getElementById(id) 就可以取到传入容器的元素了,用this.container来进行接收。 这个容器里面有很多类,我们重点是取照片,照片存在slider-list__item和slider-list_item--selected类中,this.container已经接收了元素了,我们直接进行querySelectorAll(' 把两个class写进来') ,这样我们就能把所有的照片都取到了。我们使用this.items进行接收。
-
现在来写一个函数getSelectedItem,用来返回当前选中哪张照片。
我们现在已经把所有元素都存在了this.items和this.container中, 被选中的照片的class是slider-list_item--selected,所以我们可以根据这个来写函数。 为什么不用this.items呢,因为this.items是一个NodeList对象,没有querySelector方法。 this.container.querySelector('.slider-list_item--selected') 就可以获取到选中的照片,我们const selected来进行接收。然后return selected。
-
现在需要来写一个索引函数,用来知道我们选中照片的索引是多少。
直接return Array.from(this.items).indexOf(this.getSelectedItem())
这个函数很好理解,首先this.items是通过querySelectorAll来取到的,是一个NodeList对象,需要通过Array.from先变成数组,然后通过indexOf获取索引。其参数为被选中的照片。
-
现在就可以写切换照片的函数了。
如果切换下一张,那就是索引+1,切换前一张,那就是索引-1。 所以我们最好是再写一个根据索引切换照片的函数,这样会更加方便。 slideTo 接收一个参数idx,首先我们先获取到当前选中的图片,如果图片被选中了,我们就把它的class改成slider-list__item,然后通过this.item[idx]获取到我们要显示的图片,令它的class为slider-list_item--selected。 有了这个函数我们切换起来就很方便了。
- 切换下一张,我们先得到当前选择的图片的索引,然后令该索引+1再对照片总数取余,就可以得到下一张照片的索引,然后调用slideTo函数,就可以进行切换了。