7

slider轮播组件,在各类网站上出现及其频繁,有渐隐式的,滑动式的等等一系列。
栗子在这:

但我当初学习写轮播时却被各种入门教程搞得焦头烂额。不是代码太复杂,就是封装太严重,初学者很难理清思路,今天我们就写一个最基本轮播组件(当然功能也要完整),并探寻其中的规律。

观察各类轮播组件,我们不难发现一个功能完善的组件具备如下几个特点:

  1. 前进后退按钮控制单张幻灯片

  2. 索引按钮可以直接选择某张幻灯片

  3. mouseover 可取消滑动,mouseout 恢复滑动

  4. 部分幻灯片支持无限滑动

  5. 支持手势操作

今天我们以构造一个最基本的幻灯片组件为出发点,实现前4个特点,只用50行js。

一般原理

我们本次的幻灯片是滑动式幻灯片,观察不难发现多张幻灯片其实是连续的,但我们却只能看见一张幻灯片,其它的幻灯片其实是被隐藏掉了。说起隐藏我们想起一个属性 overflow:hidden 。对,滑动式幻灯片的关键就在于隐藏。幻灯片是多张的就像一个队列一样,一般都包裹在 ul 标签的 li中,而ul外层的容器(container)--就是我们的视窗,它的宽度一般只有一张幻灯片的大小,再在其上设置overflow:hidden ,其余的幻灯片便被隐藏掉了。

幻灯片队列的宽度是各张幻灯片宽度的总和,他被固定在视窗内,我们通过改变队列的 leftmargin-left 便能控制队列的位置--哪张幻灯片可以被显示在视窗中。在js中我们会设置一个全局变量,通过控制全局变量来控制幻灯片队列的位置。

有了前面两点的基础我们就可以搞定一个普通的滑动幻灯片了,但如何让它无限滑动呢?无限滚动的方案有很多种,但大多较复杂,我们这次介绍一个最简单方案。原理是这样的,假如我们有一个幻灯片队列 1 2 3 4,我们克隆前后两个幻灯片补充到队列中变成 4 1 2 3 4 1 。当队列运动到第二个4,再次滑动到第二个1,然后迅速闪回第一个1,因为速度极快在视觉上我们无法分辨,便造成了无限滑动的假象。有图有真相哦。。?
图片描述

js控制逻辑

1.我们先克隆第一张和最后一张,放置到队列中。

const first_slide = slide_items[0].cloneNode(true);
const last_slide = slide_items[slide_items.length-1].cloneNode(true);
slide_list.insertBefore(last_slide, slide_items[0]);
slide_list.appendChild(first_slide);

2.这里有四个操作 (1). slide 函数负责滑动及主要逻辑 (2). tab 函数负责索引,动态添加类 (3). 为前后箭头添加处理逻辑 (4). 处理鼠标操作

3.在 slide 函数里我们定义一个 cycle 变量,由它来判断幻灯片是否应该循环闪回。 由 direction 判断幻灯片的滑动方向,滑动前一张为 -1 后一张后 1 ,这里的 direction 默认设置为 1 即正方向,因为 this 指向的是全局对象 window ,window 没有 prev 的 id 。在 cycle 条件里我们添加一个 transitionend 事件相当于滑动后的回掉,依赖这个事件在幻灯片滑动执行完毕后立即执行里面的闪回操作。

function slide() {
  let cycle = false;
  const direction = (this.id == 'prev')? -1: 1;
  current += direction;
  slide_list.style.left = -4*current + '00px';
  slide_list.style.transition = 'left 0.5s';
  cycle = !!(current == 0 || current > len);
  if (cycle) {
    current = (current === 0)? len : 1;
    slide_list.addEventListener("transitionend", function() {
    slide_list.style.left = -4*current + '00px';
    slide_list.style.transition = 'left 0s';
    })
  }
  tab(current-1);
}

4.在 tab 函数中动态设置类,并为每个 tab 设置 click 事件。

function tab(i) {
  slide_dots_items.forEach(function(i){ i.classList.remove('current')});
  slide_dots_items[i].classList.add('current');
}
slide_dots_items.forEach(function(i) {
  i.addEventListener('click', function() {
    current = [...slide_dots_items].indexOf(i);
    slide();
  })
});

5.设置一个 timer 计时器,每3000毫秒调用一次 slide 函数

timer = setInterval(slide,3000);

6.最后添加鼠标事件,mouseover 取消滑动,mouseout 恢复滑动。

container.onmouseover = function (){
  clearInterval(timer);
};
container.onmouseout = function (){
  timer = setInterval(slide,3000);
};

总结

滑动幻灯片的基本逻辑就是这些,主要需要一个全局变量 current 来控制滑动位置,并通过一定的限制条件来重置 current。

通过添加 transitionend 事件监听滑动是否结束从而迅速闪回,达到貌似无限滑动的效果。

本文主要以分析一个幻灯片组件的原理,探寻其中的规律为主,但是在响应式为主的设计浪潮下,我依然推荐你在项目中使用那些支持手势操作封装良好的组件。有几个出名的插件如下⛄️猜猜哪个组件需要25美金的证书?。。。

  1. slick 号称一旦拥有,今生无憾的滑动组件.....

  2. flickity 一个功能完善的滑动组件 *jqueryfree

  3. lory 也还不错


hiscc
276 声望13 粉丝

萌面大盗与阿里巴巴:-)