feat(tabs): 增强若干功能

pull/2680/head
贤心 2025-05-13 00:19:59 +08:00
parent 7138198645
commit 1b9557cdd8
4 changed files with 149 additions and 105 deletions

View File

@ -89,13 +89,12 @@ layui.use(function() {
title: 'New Tab '+ n, // 此处加 n 仅为演示区分,实际应用不需要
content: 'New Tab Content '+ n,
id: 'new-'+ n,
aaa: 'attr-'+ n, // 自定义属性,其中 aaa 可任意命名
done: function(params) {
console.log(params); // 查看返回的参数
done: function(data) {
console.log(data); // 查看返回的参数
// 给新标签头添加上下文菜单
dropdown.render($.extend({}, dropdownInst.config, {
elem: params.thisHeaderItem // 当前标签头元素
elem: data.headerItem // 新标签头元素 --- headerItem 为 2.11.2 新增
}));
}
}, opts);

View File

@ -122,6 +122,12 @@ tabs.render({
tabs.add('test', {
title: 'New Tab 1',
content: 'New Tab Content 1',
done: function(data) {
console.log(data); // 标签相关数据
// 为新标签头添加任意属性
data.headerItem.attr('lay-tips', '111');
}
});
```
@ -202,10 +208,10 @@ console.log(data);
{
options, // 标签配置信息
container, // 标签容器的相关元素
thisHeaderItem, // 当前标签头部项
thisBodyItem, // 当前标签内容项
index, // 当前标签索引
length, // 当前标签数
thisHeaderItem, // 当前活动标签头部项
thisBodyItem, // 当前活动标签内容项
index, // 当前活动标签索引
length, // 标签数
}
```
@ -228,12 +234,13 @@ var headerItem = tabs.getHeaderItem('test', 'abc'); // 获取 lay-id="abc" 的
`tabs.getBodyItem(id, index)`
- 参数 `id` : 组件的实例 ID
- 参数 `index` : 标签索引
- 参数 `index` : 标签索引或标签的 `lay-id` 属性值 <sup>2.11.2+</sup>
该方法用于获取标签内容项元素。
```js
var bodyItem = tabs.getBodyItem('test', 3); // 获取索引为 3 的标签内容项元素
var bodyItem = tabs.getBodyItem('test', 'abc'); // 获取 lay-id="abc" 的标签内容项元素
```
<h3 id="refresh" class="ws-anchor ws-bold">刷新标签视图</h3>

View File

@ -167,27 +167,40 @@
<script src="../src/layui.js"></script>
<script>
layui.use(function() {
var $ = layui.$;
var tabs = layui.tabs
var util = layui.util;
var layer = layui.layer;
var dropdown = layui.dropdown;
// 新增随机标签
var addTabs = function(opts) {
var n = Math.random()*1000 | 0; // 演示标记
opts = $.extend({
title: 'New Tab '+ n, // 此处加 n 仅为演示区分,实际应用不需要
content: 'New Tab Content '+ n,
id: 'new-'+ n,
// active: false, // 是否设为活动标签
done: function(data) {
console.log(data); // 查看返回的参数
// 为新标签头添加任意属性 --- 2.11.2+
data.headerItem.attr('lay-tips', 'tip-'+ n);
// 给新标签头添加上下文菜单
dropdown.render($.extend({}, dropdownInst.config, {
elem: data.headerItem // 新标签头元素
}));
}
}, opts);
// 添加标签到最后
tabs.add('demoTabs1', opts);
}
// 自定义事件
util.on({
add: function(){
var n = Math.random()*1000 | 0; // 演示标记
//添加标签
tabs.add('demoTabs1', {
title: 'New Tab '+ n, // 此处加 n 仅为演示区分,实际应用不需要
content: 'New Tab Content '+ n,
id: 'new-'+ n,
aaa: 'attr-'+ n, // 自定义属性,其中 aaa 可任意命名
// mode: 'curr',
done: function(params) {
console.log(params);
}
});
addTabs();
}
});
@ -226,30 +239,47 @@
});
// 为标签头添加上下文菜单
dropdown.render({
var dropdownInst = dropdown.render({
elem: '#demoTabs1 .layui-tabs-header>li',
trigger: 'contextmenu',
data: [{
title: '关闭',
type: 'this'
}, {
title: '关闭其他标签页',
type: 'other'
}, {
title: '关闭右侧标签页',
type: 'right'
title: '在右侧新增标签页',
action: 'add',
mode: 'after'
}, {
type: '-'
}, {
title: '关闭',
action: 'close',
mode: 'this',
}, {
title: '关闭其他标签页',
action: 'close',
mode: 'other'
}, {
title: '关闭右侧标签页',
action: 'close',
mode: 'right'
}, {
title: '关闭所有标签页',
type: 'all'
action: 'close',
mode: 'all'
}],
click: function(data, othis, event) {
var index = this.elem.index();
if (data.type === 'this') {
tabs.close('demoTabs1', index); // 关闭当前标签
} else {
tabs.closeMult('demoTabs1', data.type, index); // 批量关闭标签
var index = this.elem.index(); // 获取活动标签索引
// 新增标签操作
if (data.action === 'add') {
// 在当前活动标签右侧新增标签页
addTabs({
mode: data.mode,
index: index
});
} else if(data.action === 'close') { // 关闭标签操作
if (data.mode === 'this') {
tabs.close('demoTabs1', index); // 关闭当前标签
} else {
tabs.closeMult('demoTabs1', data.mode, index); // 批量关闭标签
}
}
}
});
@ -258,7 +288,7 @@
tabs.render({
elem: '#demoTabs2',
header: [
{ title: 'Tab1' },
{ title: 'Tab1', closable: false },
{ title: 'Tab2' },
{ title: 'Tab3' }
],
@ -267,9 +297,9 @@
{ content: 'Tab content 2' },
{ content: 'Tab content 3' }
],
// index: 1, //初始选中项
// index: 1, // 初始选中项
// className: 'layui-tabs-card',
// closable: true
closable: true
});

View File

@ -183,6 +183,7 @@ layui.define('component', function(exports) {
var container = that.getContainer();
var newHeaderItem = that.renderHeaderItem(opts);
var newBodyItem = that.renderBodyItem(opts);
var data = that.data();
// 选项默认值
opts = $.extend({
@ -191,7 +192,6 @@ layui.define('component', function(exports) {
// 插入方式
if (/(before|after)/.test(opts.mode)) { // 在活动标签前后插入
var data = that.data();
var hasOwnIndex = opts.hasOwnProperty('index');
var headerItem = hasOwnIndex ? that.findHeaderItem(opts.index) : data.thisHeaderItem;
var bodyItem = hasOwnIndex ? that.findBodyItem(opts.index) : data.thisHeaderItem;
@ -214,8 +214,12 @@ layui.define('component', function(exports) {
}
// 回调
var params = that.data();
typeof opts.done === 'function' && opts.done(params);
typeof opts.done === 'function' && opts.done(
$.extend(data, {
headerItem: newHeaderItem,
bodyItem: newBodyItem
})
);
};
/**
@ -238,7 +242,7 @@ layui.define('component', function(exports) {
}
// 当前标签相关数据
var params = that.data();
var data = that.data();
// 标签关闭前的事件。若非强制关闭,可则根据事件的返回结果决定是否关闭
if (!force) {
@ -246,7 +250,7 @@ layui.define('component', function(exports) {
thisHeaderItem[0],
component.CONST.MOD_NAME,
'beforeClose('+ options.id +')',
$.extend(params, {
$.extend(data, {
index: thisHeaderItem.index()
})
);
@ -273,14 +277,14 @@ layui.define('component', function(exports) {
that.roll('auto', index);
// 获取当前标签相关数据
var params = that.data();
var data = that.data();
// 标签关闭后的事件
layui.event.call(
params.thisHeaderItem[0],
data.thisHeaderItem[0],
component.CONST.MOD_NAME,
'afterClose('+ options.id +')',
params
data
);
};
@ -339,14 +343,14 @@ layui.define('component', function(exports) {
that.roll('auto');
// 回调
var params = that.data();
var data = that.data();
// 标签关闭后的事件
layui.event.call(
params.thisHeaderItem[0],
data.thisHeaderItem[0],
component.CONST.MOD_NAME,
'afterClose('+ options.id +')',
params
data
);
};
@ -361,7 +365,7 @@ layui.define('component', function(exports) {
var that = this;
var options = that.config;
var index = thisHeaderItem.index();
var index = thisHeaderItem.attr('lay-id') || thisHeaderItem.index();
var thatA = thisHeaderItem.find('a');
// 是否存在跳转链接
var isLink = typeof thatA.attr('href') === 'string' && thatA.attr('target') === '_blank';
@ -374,7 +378,7 @@ layui.define('component', function(exports) {
}
// 当前标签相关数据
var params = that.data();
var data = that.data();
// 标签关闭前的事件。若非强制关闭,可则根据事件的返回结果决定是否关闭
if (!force) {
@ -382,10 +386,10 @@ layui.define('component', function(exports) {
thisHeaderItem[0],
component.CONST.MOD_NAME,
'beforeChange('+ options.id +')',
$.extend(params, {
$.extend(data, {
from: {
index: params.index,
headerItem: params.thisHeaderItem
index: data.index,
headerItem: data.thisHeaderItem
},
to: {
index: thisHeaderItem.index(),
@ -411,14 +415,14 @@ layui.define('component', function(exports) {
that.roll('auto', index);
// 重新获取标签相关数据
var params = that.data();
var data = that.data();
// 标签切换后的事件
layui.event.call(
params.thisHeaderItem[0],
data.thisHeaderItem[0],
component.CONST.MOD_NAME,
'afterChange('+ options.id +')',
params
data
);
};
@ -431,17 +435,8 @@ layui.define('component', function(exports) {
var options = that.config;
var headerItem = $(opts.headerItem || options.headerItem || '<li></li>');
headerItem.html(opts.title || 'New Tab');
// 追加属性
layui.each(opts, function(key, value){
if(/^(title|content|mode|done)$/.test(key)) return;
headerItem.attr('lay-'+ key, value);
});
// 追加标签关闭元素
that.appendClose(headerItem, opts);
headerItem.html(opts.title || 'New Tab').attr('lay-id', opts.id);
that.appendClose(headerItem, opts); // 追加标签关闭元素
return headerItem;
};
@ -450,11 +445,11 @@ layui.define('component', function(exports) {
* @param {Object} opts - 标签项配置信息
*/
Class.prototype.renderBodyItem = function(opts) {
var that = this
var options = that.config
var that = this;
var options = that.config;
var bodyItem = $(opts.bodyItem || options.bodyItem || '<div class="'+ component.CONST.ITEM +'"></div>');
bodyItem.html(opts.content || '');
bodyItem.html(opts.content || '').attr('lay-id', opts.id);
return bodyItem;
};
@ -472,7 +467,7 @@ layui.define('component', function(exports) {
opts = opts || {};
// 不可关闭项
if (opts.closable === 'false' || headerItem.attr('lay-closable') === 'false') {
if (opts.closable == false || headerItem.attr('lay-closable') === 'false') {
return;
}
@ -493,16 +488,15 @@ layui.define('component', function(exports) {
var options = that.config;
var container = that.getContainer();
// 是否开启关闭
if (options.closable) {
container.header.items.each(function() {
that.appendClose($(this));
});
} else {
container.header.items.each(function() {
$(this).find('.'+ component.CONST.CLOSE).remove();
});
}
container.header.items.each(function() {
var $this = $(this);
// 是否开启关闭
if (options.closable) {
that.appendClose($this);
} else {
$this.find('.'+ component.CONST.CLOSE).remove();
}
});
};
/**
@ -652,25 +646,36 @@ layui.define('component', function(exports) {
};
/**
* 根据 id index 获取相关标签头部项
* @param {number|string} index - 标签索引或 id
* 获取标签头部项
* @param {number|string} index - 标签索引或 lay-id
*/
Class.prototype.findHeaderItem = function(index) {
if(!(
typeof index === 'number'
|| (typeof index === 'string' && index)
)) return;
var headerItems = this.getContainer().header.items;
var item = headerItems.filter('[lay-id="'+ index +'"]');
return item[0] ? item : headerItems.eq(index);
var container = this.getContainer();
var headerItems = container.header.items;
var headerItem = headerItems.filter('[lay-id="'+ index +'"]');
return headerItem[0] ? headerItem : headerItems.eq(index);
};
/**
* 根据 index 获取相关标签内容项
* @param {number} index - 标签索引
* 获取标签内容项
* @param {number} index - 标签索引lay-id
*/
Class.prototype.findBodyItem = function(index) {
return this.getContainer().body.items.eq(index);
var container = this.getContainer();
var bodyItems = container.body.items;
var bodyItem = bodyItems.filter('[lay-id="'+ index +'"]');
return bodyItem[0] ? bodyItem : function() {
// 若未匹配到 lay-id 对应内容项,则继续匹配对应头部项
var headerItems = container.header.items;
var headerItem = headerItems.filter('[lay-id="'+ index +'"]');
if (headerItem[0]) {
index = headerItem.index();
}
return bodyItems.eq(index);
}();
};
/**
@ -687,11 +692,11 @@ layui.define('component', function(exports) {
return {
options: options, // 标签配置信息
container: container, // 标签容器的相关元素
thisHeaderItem: thisHeaderItem, // 当前标签头部项
thisBodyItem: that.findBodyItem(index), // 当前标签内容项
index: index, // 当前标签索引
length: container.header.items.length // 当前标签数
}
thisHeaderItem: thisHeaderItem, // 当前活动标签头部项
thisBodyItem: that.findBodyItem(index), // 当前活动标签内容项
index: index, // 当前活动标签索引
length: container.header.items.length // 标签数
};
};
// 扩展组件接口
@ -715,8 +720,11 @@ layui.define('component', function(exports) {
*/
close: function(id, index, force) {
var that = component.getInst(id);
if(!that) return;
if(index === undefined) index = that.data().index; // index 若不传,则表示关闭当前标签
if (!that) return;
// index 若不传,则表示关闭当前标签
if (index === undefined) {
index = that.data().index;
}
that.close(that.findHeaderItem(index), force);
},
@ -755,7 +763,7 @@ layui.define('component', function(exports) {
/**
* 获取标签指定头部项
* @param {string} id - 渲染时的实例 ID
* @param {number} index - 标签索引
* @param {number} index - 标签索引lay-id
* @returns
*/
getHeaderItem: function(id, index) {
@ -767,7 +775,7 @@ layui.define('component', function(exports) {
/**
* 获取标签指定内容项
* @param {string} id - 渲染时的实例 ID
* @param {number} index - 标签索引
* @param {number} index - 标签索引lay-id
* @returns
*/
getBodyItem: function(id, index) {