mirror of
https://github.com/layui/layui.git
synced 2026-02-09 02:09:18 +08:00
refactor(carousel): 使用 component 模块重构组件 (#2857)
This commit is contained in:
@@ -25,6 +25,7 @@ div[carousel-item]>*:nth-child(2n+1){background-color: #16baaa;}
|
||||
| API | 描述 |
|
||||
| --- | --- |
|
||||
| var carousel = layui.carousel | 获得 `carousel` 模块。 |
|
||||
| [基础接口](../component/#export) <sup>2.13+</sup> | 该组件由 `component` 构建,因此继承其提供的基础接口。|
|
||||
| [var inst = carousel.render(options)](#render) | carousel 组件渲染,核心方法。 |
|
||||
| [inst.reload(options)](#reload) | 轮播实例重载 |
|
||||
| [inst.goto(index)](#goto) <sup>2.8+</sup> | 轮播切换到特定下标 |
|
||||
|
||||
@@ -84,7 +84,7 @@ layui.use('carousel', function(){
|
||||
// trigger: 'hover'
|
||||
});
|
||||
|
||||
// carInst.goto(1);
|
||||
// console.log(carInst); carInst.goto(1);
|
||||
|
||||
// 事件
|
||||
/*
|
||||
|
||||
@@ -1,100 +1,62 @@
|
||||
/**
|
||||
* carousel 轮播模块
|
||||
* MIT Licensed
|
||||
* carousel
|
||||
* 轮播
|
||||
*/
|
||||
|
||||
layui.define(['jquery', 'lay'], function(exports) {
|
||||
layui.define('component', function(exports) {
|
||||
"use strict";
|
||||
|
||||
var $ = layui.$;
|
||||
var lay = layui.lay;
|
||||
|
||||
var hint = layui.hint();
|
||||
var device = layui.device();
|
||||
|
||||
// 外部接口
|
||||
var carousel = {
|
||||
config: {}, // 全局配置项
|
||||
|
||||
// 设置全局项
|
||||
set: function(options) {
|
||||
var that = this;
|
||||
that.config = $.extend({}, that.config, options);
|
||||
return that;
|
||||
},
|
||||
|
||||
// 事件
|
||||
on: function(events, callback) {
|
||||
return layui.onevent.call(this, MOD_NAME, events, callback);
|
||||
}
|
||||
};
|
||||
|
||||
// 字符常量
|
||||
var MOD_NAME = 'carousel';
|
||||
var ELEM = '.layui-carousel';
|
||||
var THIS = 'layui-this';
|
||||
var SHOW = 'layui-show';
|
||||
var HIDE = 'layui-hide';
|
||||
var DISABLED = 'layui-disabled'
|
||||
|
||||
var ELEM_ITEM = '>*[carousel-item]>*';
|
||||
var ELEM_LEFT = 'layui-carousel-left';
|
||||
var ELEM_RIGHT = 'layui-carousel-right';
|
||||
var ELEM_PREV = 'layui-carousel-prev';
|
||||
var ELEM_NEXT = 'layui-carousel-next';
|
||||
var ELEM_ARROW = 'layui-carousel-arrow';
|
||||
var ELEM_IND = 'layui-carousel-ind';
|
||||
|
||||
// 构造器
|
||||
var Class = function(options) {
|
||||
var that = this;
|
||||
that.config = $.extend({}, that.config, carousel.config, options);
|
||||
that.render();
|
||||
};
|
||||
// 创建组件
|
||||
var component = layui.component({
|
||||
name: 'carousel',
|
||||
|
||||
// 默认配置
|
||||
Class.prototype.config = {
|
||||
config: {
|
||||
width: '600px',
|
||||
height: '280px',
|
||||
full: false, // 是否全屏
|
||||
arrow: 'hover', // 切换箭头默认显示状态:hover/always/none
|
||||
indicator: 'inside', // 指示器位置:inside/outside/none
|
||||
autoplay: true, // 是否自动切换
|
||||
interval: 3000, // 自动切换的时间间隔,不能低于800ms
|
||||
interval: 3000, // 自动切换的时间间隔,不能低于 800ms
|
||||
anim: '', // 动画类型:default/updown/fade
|
||||
trigger: 'click', // 指示器的触发方式:click/hover
|
||||
index: 0 // 初始开始的索引
|
||||
};
|
||||
},
|
||||
|
||||
// 轮播渲染
|
||||
Class.prototype.render = function(){
|
||||
CONST: {
|
||||
ELEM: 'layui-carousel',
|
||||
ELEM_ITEM: '>*[carousel-item]>*',
|
||||
ELEM_LEFT: 'layui-carousel-left',
|
||||
ELEM_RIGHT: 'layui-carousel-right',
|
||||
ELEM_PREV: 'layui-carousel-prev',
|
||||
ELEM_NEXT: 'layui-carousel-next',
|
||||
ELEM_ARROW: 'layui-carousel-arrow',
|
||||
ELEM_IND: 'layui-carousel-ind'
|
||||
},
|
||||
|
||||
// 渲染
|
||||
render: function() {
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
|
||||
// 若 elem 非唯一,则拆分为多个实例
|
||||
var elem = $(options.elem);
|
||||
if(elem.length > 1){
|
||||
layui.each(elem, function(){
|
||||
carousel.render($.extend({}, options, {
|
||||
elem: this
|
||||
}));
|
||||
});
|
||||
return that;
|
||||
that.elemItem = options.elem.find(CONST.ELEM_ITEM);
|
||||
|
||||
if (options.index < 0) {
|
||||
options.index = 0;
|
||||
}
|
||||
if (options.index >= that.elemItem.length) {
|
||||
options.index = that.elemItem.length - 1;
|
||||
}
|
||||
if (options.interval < 800) {
|
||||
options.interval = 800;
|
||||
}
|
||||
|
||||
// 合并 lay-options 属性上的配置信息
|
||||
$.extend(options, lay.options(elem[0]));
|
||||
|
||||
options.elem = $(options.elem);
|
||||
if(!options.elem[0]) return;
|
||||
that.elemItem = options.elem.find(ELEM_ITEM);
|
||||
|
||||
if(options.index < 0) options.index = 0;
|
||||
if(options.index >= that.elemItem.length) options.index = that.elemItem.length - 1;
|
||||
if(options.interval < 800) options.interval = 800;
|
||||
|
||||
// 是否全屏模式
|
||||
if(options.full){
|
||||
if (options.full) {
|
||||
options.elem.css({
|
||||
position: 'fixed',
|
||||
width: '100%',
|
||||
@@ -111,25 +73,38 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
options.elem.attr('lay-anim', options.anim);
|
||||
|
||||
// 初始焦点状态
|
||||
that.elemItem.eq(options.index).addClass(THIS);
|
||||
that.elemItem.eq(options.index).addClass(CONST.CLASS_THIS);
|
||||
|
||||
// 指示器、箭头等动作
|
||||
that.indicator();
|
||||
that.arrow();
|
||||
that.autoplay();
|
||||
},
|
||||
|
||||
if (that.elemItem.length > 1) {
|
||||
that.events();
|
||||
}
|
||||
};
|
||||
|
||||
// 重置轮播
|
||||
Class.prototype.reload = function(options){
|
||||
// 扩展实例方法
|
||||
extendsInstance: function() {
|
||||
var that = this;
|
||||
clearInterval(that.timer);
|
||||
that.config = $.extend({}, that.config, options);
|
||||
that.render();
|
||||
var options = that.config;
|
||||
|
||||
// 确保与文档描述一致
|
||||
return {
|
||||
elemInd: that.elemInd,
|
||||
elemItem: that.elemItem,
|
||||
timer: that.timer,
|
||||
goto: function (index) {
|
||||
that.goto(index);
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
var CONST = component.CONST;
|
||||
|
||||
/**
|
||||
* 扩展组件原型方法
|
||||
*/
|
||||
|
||||
var Class = component.Class;
|
||||
|
||||
// 获取上一个等待条目的索引
|
||||
Class.prototype.prevIndex = function(){
|
||||
@@ -209,16 +184,16 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
|
||||
// 模板
|
||||
var tplArrow = $([
|
||||
'<button type="button" class="layui-icon '+ (options.anim === 'updown' ? 'layui-icon-up' : 'layui-icon-left') + ' ' + ELEM_ARROW +'" lay-type="sub"></button>',
|
||||
'<button type="button" class="layui-icon '+ (options.anim === 'updown' ? 'layui-icon-down' : 'layui-icon-right') + ' ' + ELEM_ARROW +'" lay-type="add"></button>'
|
||||
'<button type="button" class="layui-icon '+ (options.anim === 'updown' ? 'layui-icon-up' : 'layui-icon-left') + ' ' + CONST.ELEM_ARROW +'" lay-type="sub"></button>',
|
||||
'<button type="button" class="layui-icon '+ (options.anim === 'updown' ? 'layui-icon-down' : 'layui-icon-right') + ' ' + CONST.ELEM_ARROW +'" lay-type="add"></button>'
|
||||
].join(''));
|
||||
|
||||
// 预设基础属性
|
||||
options.elem.attr('lay-arrow', options.arrow);
|
||||
|
||||
// 避免重复插入
|
||||
if(options.elem.find('.'+ELEM_ARROW)[0]){
|
||||
options.elem.find('.'+ELEM_ARROW).remove();
|
||||
if(options.elem.find('.'+CONST.ELEM_ARROW)[0]){
|
||||
options.elem.find('.'+CONST.ELEM_ARROW).remove();
|
||||
}
|
||||
itemsCount > 1 ? options.elem.append(tplArrow) : tplArrow.remove();
|
||||
|
||||
@@ -249,7 +224,7 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
var itemsCount = that.elemItem.length;
|
||||
|
||||
// 模板
|
||||
var tplInd = that.elemInd = $(['<div class="'+ ELEM_IND +'"><ul>',
|
||||
var tplInd = that.elemInd = $(['<div class="'+ CONST.ELEM_IND +'"><ul>',
|
||||
function(){
|
||||
var li = [];
|
||||
layui.each(that.elemItem, function(index){
|
||||
@@ -263,8 +238,8 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
options.elem.attr('lay-indicator', options.indicator);
|
||||
|
||||
// 避免重复插入
|
||||
if(options.elem.find('.'+ELEM_IND)[0]){
|
||||
options.elem.find('.'+ELEM_IND).remove();
|
||||
if(options.elem.find('.'+CONST.ELEM_IND)[0]){
|
||||
options.elem.find('.'+CONST.ELEM_IND).remove();
|
||||
}
|
||||
|
||||
itemsCount > 1 ? options.elem.append(tplInd) : tplInd.remove();
|
||||
@@ -293,30 +268,30 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
// 滑动方向
|
||||
if(type === 'sub'){
|
||||
that.subIndex(num);
|
||||
elemItem.eq(options.index).addClass(ELEM_PREV);
|
||||
elemItem.eq(options.index).addClass(CONST.ELEM_PREV);
|
||||
setTimeout(function(){
|
||||
elemItem.eq(thisIndex).addClass(ELEM_RIGHT);
|
||||
elemItem.eq(options.index).addClass(ELEM_RIGHT);
|
||||
elemItem.eq(thisIndex).addClass(CONST.ELEM_RIGHT);
|
||||
elemItem.eq(options.index).addClass(CONST.ELEM_RIGHT);
|
||||
}, 50);
|
||||
} else { // 默认递增滑
|
||||
that.addIndex(num);
|
||||
elemItem.eq(options.index).addClass(ELEM_NEXT);
|
||||
elemItem.eq(options.index).addClass(CONST.ELEM_NEXT);
|
||||
setTimeout(function(){
|
||||
elemItem.eq(thisIndex).addClass(ELEM_LEFT);
|
||||
elemItem.eq(options.index).addClass(ELEM_LEFT);
|
||||
elemItem.eq(thisIndex).addClass(CONST.ELEM_LEFT);
|
||||
elemItem.eq(options.index).addClass(CONST.ELEM_LEFT);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
// 移除过渡类
|
||||
setTimeout(function(){
|
||||
elemItem.removeClass(THIS + ' ' + ELEM_PREV + ' ' + ELEM_NEXT + ' ' + ELEM_LEFT + ' ' + ELEM_RIGHT);
|
||||
elemItem.eq(options.index).addClass(THIS);
|
||||
setTimeout(function() {
|
||||
elemItem.removeClass(CONST.CLASS_THIS + ' ' + CONST.ELEM_PREV + ' ' + CONST.ELEM_NEXT + ' ' + CONST.ELEM_LEFT + ' ' + CONST.ELEM_RIGHT);
|
||||
elemItem.eq(options.index).addClass(CONST.CLASS_THIS);
|
||||
that.haveSlide = false; // 解锁
|
||||
}, 350);
|
||||
|
||||
// 指示器焦点
|
||||
that.elemInd.find('li').eq(options.index).addClass(THIS)
|
||||
.siblings().removeClass(THIS);
|
||||
that.elemInd.find('li').eq(options.index).addClass(CONST.CLASS_THIS)
|
||||
.siblings().removeClass(CONST.CLASS_THIS);
|
||||
|
||||
that.haveSlide = true;
|
||||
|
||||
@@ -328,7 +303,7 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
};
|
||||
|
||||
typeof options.change === 'function' && options.change(params);
|
||||
layui.event.call(this, MOD_NAME, 'change('+ filter +')', params);
|
||||
layui.event.call(this, CONST.MOD_NAME, 'change('+ filter +')', params);
|
||||
};
|
||||
|
||||
// 事件处理
|
||||
@@ -365,12 +340,7 @@ layui.define(['jquery', 'lay'], function(exports) {
|
||||
options.elem.data('haveEvents', true);
|
||||
};
|
||||
|
||||
// 核心入口
|
||||
carousel.render = function(options){
|
||||
return new Class(options);
|
||||
};
|
||||
|
||||
exports(MOD_NAME, carousel);
|
||||
exports(CONST.MOD_NAME, component);
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user