boostrap轮播图实现剖析
说明
实现来源于:
- https://github.com/twbs/bootstrap/blob/v3.3.7/js/carousel.js
- https://github.com/twbs/bootstrap/blob/v3.3.7/less/carousel.less
- 样式相关改动:
- 将less转换为css;
- 移除样式中关于左右翻页, icon相关样式;
- 移除样式中的 > ,个人看着别扭而已;
- js逻辑实现相关改动:
- 移除对jquery的依赖,dom操作全部由原生js完成;
- 简化实现,目前一个html页面只允许存在一个轮播图;
- 自定义事件使用CustomEvent完成
- 移除一些适配相关代码,出于精简代码考虑
原理介绍 使用js给dom元素动态添加/删除类方式实现控制元素变化;
关键实现:
// type 为 next或者 prev
var $active = this.$element.querySelector(".item.active");
var $next = next || this.getItemForDirection(type, $active);
var direction = type == "next" ? "left" : "right";
utils.addClass($next, type);
$next.offsetWidth // force reflow
utils.addClass($active, direction);
utils.addClass($next, direction);
const that = this;
function transitionHandler () {
utils.removeClass($next, type);
utils.removeClass($next, direction);
utils.addClass($next, 'active');
utils.removeClass($active, 'active');
utils.removeClass($active, direction);
that.sliding = false;
setTimeout(function () {
$active.removeEventListener('transitionend', transitionHandler);
}, 0)
}
$active.addEventListener('transitionend', transitionHandler);
举例说明:
假设第一张图片为 p1, 第二张图片为 p2,
以p1 -> p2为例:
- next为 p2;
- type 为 'next',direction 为 'left';
- 给$next(即p2)添加 'next' 类,其样式为:
{
position: absolute;
top: 0;
width: 100%;
left: 0;
transform: translate(100%, 0);
}
即在p1的右边展示,left为0,然后使用translate右移自身宽度
- $next.offsetWidth 保证当前设置生效,以防浏览器做js操作dom进行一些优化
- 给$active(即p1)添加 'left' 类, 其样式添加:
{
left: 0;
transform: translate(-100%, 0);
}
即左移自身宽度
- 给 $next(即p2) 添加 'left' 类, 其样式由:
{
left: 0;
transform: translate(100%, 0);
}
被覆盖为:
{
left: 0;
transform: translate(0, 0);
}
即左移自身宽度
- 这样就完成了图片由p1切换为p2,然后监听
transitionend
事件,移除 'next'、'left'、'right'等中间态的class, 给 active(即p1)的 'active' 类