slider轮播组件,在各类网站上出现及其频繁,有渐隐式的,滑动式的等等一系列。
栗子在这:
但我当初学习写轮播时却被各种入门教程搞得焦头烂额。不是代码太复杂,就是封装太严重,初学者很难理清思路,今天我们就写一个最基本轮播组件(当然功能也要完整),并探寻其中的规律。
观察各类轮播组件,我们不难发现一个功能完善的组件具备如下几个特点:
前进后退按钮控制单张幻灯片
索引按钮可以直接选择某张幻灯片
mouseover 可取消滑动,mouseout 恢复滑动
部分幻灯片支持无限滑动
支持手势操作
今天我们以构造一个最基本的幻灯片组件为出发点,实现前4个特点,只用50行js。
一般原理
我们本次的幻灯片是滑动式幻灯片,观察不难发现多张幻灯片其实是连续的,但我们却只能看见一张幻灯片,其它的幻灯片其实是被隐藏掉了。说起隐藏我们想起一个属性 overflow:hidden
。对,滑动式幻灯片的关键就在于隐藏。幻灯片是多张的就像一个队列一样,一般都包裹在 ul
标签的 li
中,而ul
外层的容器(container)--就是我们的视窗,它的宽度一般只有一张幻灯片的大小,再在其上设置overflow:hidden
,其余的幻灯片便被隐藏掉了。
幻灯片队列的宽度是各张幻灯片宽度的总和,他被固定在视窗内,我们通过改变队列的 left
或 margin-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美金的证书?。。。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。