update code

pull/2730/head
sight 2025-06-20 13:44:54 +08:00
parent c5dfff8016
commit a6e5a3deaf
2 changed files with 59 additions and 34 deletions

View File

@ -105,15 +105,26 @@
<td>anim <sup>2.11.4</sup></td> <td>anim <sup>2.11.4</sup></td>
<td> <td>
自定义切换标签时的过渡效果。例如 设置标签切换时的动画效果。传入一个对象,包含以下属性
`['layui-anim layui-anim-fadein', 'layui-anim layui-anim-fadeout']` - `enterClass`:进入动画 CSS 类名
- `leaveClass`:离开动画 CSS 类名
例如:
```js
anim: {
enterClass: 'layui-anim layui-anim-fadein',
leaveClass: 'layui-anim layui-anim-fadeout'
}
```
</td> </td>
<td>Array</td> <td>`{enterClass: string, leaveClass: string}`</td>
<td> <td>
undefined -
</td> </td>
</tr> </tr>

View File

@ -8,7 +8,7 @@ layui.define('component', function(exports) {
var $ = layui.$; var $ = layui.$;
var isSupportsAnimationend = supportsAnimationEnd(); var animEnd = getSupportsAnimationEnd();
// 创建组件 // 创建组件
var component = layui.component({ var component = layui.component({
@ -28,7 +28,7 @@ layui.define('component', function(exports) {
BODY: 'layui-tabs-body', BODY: 'layui-tabs-body',
ITEM: 'layui-tabs-item', ITEM: 'layui-tabs-item',
CARD: 'layui-tabs-card', CARD: 'layui-tabs-card',
ANIM_END_EVENT_NAME: 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend' EVENT_ANIMATIONEND: animEnd.eventName
}, },
// 渲染 // 渲染
@ -280,11 +280,11 @@ layui.define('component', function(exports) {
} }
// 移除元素 // 移除元素
// 延迟移除元素,否则会导致元素移除后,无法触发 animationend 事件 var bodyItemElem = that.findBodyItem(layid || index)
var waitRemoveEl = that.findBodyItem(layid || index) if(options.anim && bodyItemElem.hasClass(component.CONST.CLASS_SHOW)){
setTimeout(function(){ bodyItemElem.trigger(component.CONST.EVENT_ANIMATIONEND);
waitRemoveEl.remove(); }
}, 450) bodyItemElem.remove();
thisHeaderItem.remove(); thisHeaderItem.remove();
that.roll('auto', index); that.roll('auto', index);
@ -354,6 +354,9 @@ layui.define('component', function(exports) {
var isCloseAll = mode === 'all'; // 关闭所有标签 var isCloseAll = mode === 'all'; // 关闭所有标签
if (isCloseOther || isCloseRight || isCloseLeft || isCloseAll) { if (isCloseOther || isCloseRight || isCloseLeft || isCloseAll) {
if(options.anim && bodyItem.hasClass(component.CONST.CLASS_SHOW)){
bodyItem.trigger(component.CONST.EVENT_ANIMATIONEND);
}
$this.remove(); $this.remove();
bodyItem.remove(); bodyItem.remove();
} }
@ -377,7 +380,6 @@ layui.define('component', function(exports) {
* 切换标签 * 切换标签
* @param {Object} thisHeaderItem - 当前标签头部项元素 * @param {Object} thisHeaderItem - 当前标签头部项元素
* @param {boolean} [force=false] - 是否强制切换 * @param {boolean} [force=false] - 是否强制切换
* @returns
*/ */
Class.prototype.change = function(thisHeaderItem, force) { Class.prototype.change = function(thisHeaderItem, force) {
if (!thisHeaderItem || !thisHeaderItem[0]) return; if (!thisHeaderItem || !thisHeaderItem[0]) return;
@ -431,11 +433,11 @@ layui.define('component', function(exports) {
// 执行标签内容切换 // 执行标签内容切换
var bodyElem = that.findBodyItem(layid || index); var bodyElem = that.findBodyItem(layid || index);
if( if(
isSupportsAnimationend animEnd.isSupported
&& options.anim && options.anim
&& layui.type(options.anim) === 'array' && layui.type(options.anim) === 'object'
){ ){
that.applyAnim(data.thisBodyItem, bodyElem); that.changeContentWithAnim(data.thisBodyItem, bodyElem);
}else{ }else{
bodyElem.addClass(component.CONST.CLASS_SHOW).siblings().removeClass(component.CONST.CLASS_SHOW); bodyElem.addClass(component.CONST.CLASS_SHOW).siblings().removeClass(component.CONST.CLASS_SHOW);
} }
@ -454,28 +456,31 @@ layui.define('component', function(exports) {
); );
}; };
Class.prototype.applyAnim = function(oldActiveContentEl, activeContentEl){ /**
* 切换标签内容项带过渡动画
* @param {jQUery} oldActiveContentEl - 旧的标签内容项元素
* @param {jQUery} activeContentEl - 新的标签内容项元素
*/
Class.prototype.changeContentWithAnim = function(oldActiveContentEl, activeContentEl){
var that = this; var that = this;
var options = that.config; var options = that.config;
var onlyIn = !isConnectedElement(oldActiveContentEl[0]) || oldActiveContentEl[0] === activeContentEl[0]; // 处理初始渲染 var onlyIn = !isConnectedElement(oldActiveContentEl[0]) || oldActiveContentEl[0] === activeContentEl[0]; // 处理初始渲染
var animInClass = options.anim[0];
var animOutClass = options.anim[1];
var transitionOut = function(cb){ var transitionOut = function(cb){
oldActiveContentEl oldActiveContentEl
.addClass(animOutClass) .addClass(options.anim.leaveClass)
.one(component.CONST.ANIM_END_EVENT_NAME, function() { .one(component.CONST.EVENT_ANIMATIONEND, function() {
oldActiveContentEl.removeClass(component.CONST.CLASS_SHOW).removeClass(animOutClass); oldActiveContentEl.removeClass(component.CONST.CLASS_SHOW).removeClass(options.anim.leaveClass);
cb && cb(); cb && cb();
}) })
} }
var transitionIn = function(){ var transitionIn = function(){
activeContentEl activeContentEl
.addClass(component.CONST.CLASS_SHOW) .addClass(component.CONST.CLASS_SHOW)
.addClass(animInClass) .addClass(options.anim.enterClass)
.one(component.CONST.ANIM_END_EVENT_NAME, function() { .one(component.CONST.EVENT_ANIMATIONEND, function() {
activeContentEl.removeClass(animInClass); activeContentEl.removeClass(options.anim.enterClass);
}); });
} }
if(onlyIn){ if(onlyIn){
@ -871,22 +876,31 @@ layui.define('component', function(exports) {
/** /**
* 检测当前环境是否支持动画结束事件 * 检测当前环境是否支持动画结束事件
* @returns {boolean} - 如果支持动画结束事件则返回 true否则返回 false * @returns {{isSupported: boolean, eventName: string}}
*/ */
function supportsAnimationEnd() { function getSupportsAnimationEnd() {
if(typeof AnimationEvent !== 'undefined'){ var vender = '';
return true; var eventsMap = {
} '': 'animationend',
'o': 'oanimationend',
'MS': 'MSAnimationEnd',
'moz': 'mozAnimationEnd',
'webkit': 'webkitAnimationEnd'
};
var el = document.createElement('div'); var el = document.createElement('div');
var prefixes = ['', 'webkit', 'moz', 'MS', 'o']; var prefixes = ['', 'webkit', 'moz', 'MS', 'o'];
var isSupport = prefixes.some(function(prefix){ var isSupported = prefixes.some(function(prefix){
var eventName = 'on' + prefix.toLowerCase() + 'animationend' var eventName = 'on' + prefix.toLowerCase() + 'animationend';
vender = prefix;
return eventName in el; return eventName in el;
}); });
el = null; el = null;
return isSupport; return {
isSupported: isSupported,
eventName: eventsMap[vender]
}
}; };
/** /**