mirror of https://github.com/layui/layui
fix(tabs): 优化 close 方法在标签顺序打乱时传入 lay-id 的支持 (#2690)
* fix(tabs): 优化 close 方法在标签顺序打乱时传入 lay-id 的支持 * fix(tabs): 优化 closeMult 方法 index 参数值为 lay-id 时的无效问题 * fix(tabs): 优化 `getHeaderItem` 等方法的 `index` 参数的类型检测pull/2734/head
parent
ac8d5ccc30
commit
1eb01c6706
|
@ -136,7 +136,7 @@ tabs.add('test', {
|
||||||
`tabs.close(id, index, force)`
|
`tabs.close(id, index, force)`
|
||||||
|
|
||||||
- 参数 `id` : 组件的实例 ID
|
- 参数 `id` : 组件的实例 ID
|
||||||
- 参数 `index` : 标签索引或标签的 `lay-id` 属性值
|
- 参数 `index` : 若传入 number 类型,则为标签索引;若传入 string 类型,则为标签的 `lay-id` 属性值
|
||||||
- 参数 `force` : 是否强制关闭。若设置 `true` 将忽略 `beforeClose` 事件行为。默认 `false`
|
- 参数 `force` : 是否强制关闭。若设置 `true` 将忽略 `beforeClose` 事件行为。默认 `false`
|
||||||
|
|
||||||
该方法用于关闭指定的标签项。
|
该方法用于关闭指定的标签项。
|
||||||
|
@ -156,19 +156,23 @@ tabs.close('test', 'abc'); // 关闭 lay-id="abc" 的标签
|
||||||
|
|
||||||
| mode | 描述 |
|
| mode | 描述 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| other | 关闭除当前标签外的所有标签 |
|
| other | 关闭除当前标签外的其他标签 |
|
||||||
| right | 关闭当前标签及右侧标签 |
|
| right | 关闭当前标签的右侧所有标签 |
|
||||||
| all | 关闭所有标签 |
|
| all | 关闭所有标签 |
|
||||||
|
|
||||||
- 参数 `index` : 活动标签的索引或 `lay-id` 属性值,默认取当前选中标签的索引。一般用于标签右键事件。
|
- 参数 `index` : 活动标签的索引或 `lay-id` 属性值,默认取当前选中标签的索引。一般用于标签右键事件。
|
||||||
|
|
||||||
该方法用于批量关闭标签。
|
该方法用于批量关闭标签,若标签项已设置不允许关闭(`lay-closable="false"`),则操作将被忽略。
|
||||||
|
|
||||||
```js
|
```js
|
||||||
tabs.closeMult(id, 'other'); // 关闭除当前标签外的所有标签
|
tabs.closeMult(id, 'other'); // 关闭除当前活动标签外的其他标签
|
||||||
tabs.closeMult(id, 'other', 3); // 关闭除索引为 3 的标签外的所有标签
|
tabs.closeMult(id, 'other', 3); // 关闭除索引为 3 的标签外的其他标签
|
||||||
tabs.closeMult(id, 'right'); // 关闭当前标签及右侧标签
|
tabs.closeMult(id, 'other', 'ccc'); // 关闭除 lay-id="ccc" 的标签外的其他标签
|
||||||
|
|
||||||
|
tabs.closeMult(id, 'right'); // 关闭当前活动标签的右侧所有标签
|
||||||
tabs.closeMult(id, 'right', 3); // 关闭索引为 3 的标签的右侧所有标签
|
tabs.closeMult(id, 'right', 3); // 关闭索引为 3 的标签的右侧所有标签
|
||||||
|
tabs.closeMult(id, 'right', 'ccc'); // 关闭 lay-id="ccc" 的标签的右侧所有标签
|
||||||
|
|
||||||
tabs.closeMult(id, 'all'); // 关闭所有标签
|
tabs.closeMult(id, 'all'); // 关闭所有标签
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -220,7 +224,7 @@ console.log(data);
|
||||||
`tabs.getHeaderItem(id, index)`
|
`tabs.getHeaderItem(id, index)`
|
||||||
|
|
||||||
- 参数 `id` : 组件的实例 ID
|
- 参数 `id` : 组件的实例 ID
|
||||||
- 参数 `index` : 标签索引或标签的 `lay-id` 属性值
|
- 参数 `index` : 若传入 number 类型,则为标签索引;若传入 string 类型,则为标签的 `lay-id` 属性值
|
||||||
|
|
||||||
该方法用于获取标签头部项元素。
|
该方法用于获取标签头部项元素。
|
||||||
|
|
||||||
|
@ -234,7 +238,7 @@ var headerItem = tabs.getHeaderItem('test', 'abc'); // 获取 lay-id="abc" 的
|
||||||
`tabs.getBodyItem(id, index)`
|
`tabs.getBodyItem(id, index)`
|
||||||
|
|
||||||
- 参数 `id` : 组件的实例 ID
|
- 参数 `id` : 组件的实例 ID
|
||||||
- 参数 `index` : 标签索引或标签的 `lay-id` 属性值 <sup>2.11.2+</sup>
|
- 参数 `index` : 若传入 number 类型,则为标签索引;若传入 string 类型,则为标签的 `lay-id` 属性值 <sup>2.11.2+</sup>
|
||||||
|
|
||||||
该方法用于获取标签内容项元素。
|
该方法用于获取标签内容项元素。
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h2>打乱标签顺序:</h2>
|
||||||
|
<div class="layui-tabs" lay-options="{closable: true}">
|
||||||
|
<ul class="layui-tabs-header">
|
||||||
|
<li lay-id="fff">Tab6</li>
|
||||||
|
<li lay-id="eee">Tab5</li>
|
||||||
|
<li lay-id="ccc">Tab3</li>
|
||||||
|
<li lay-id="bbb">Tab2</li>
|
||||||
|
<li lay-id="aaa">Tab1</li>
|
||||||
|
<li lay-id="ddd">Tab4</li>
|
||||||
|
</ul>
|
||||||
|
<div class="layui-tabs-body">
|
||||||
|
<div class="layui-tabs-item" lay-id="aaa">Tab Content-1</div>
|
||||||
|
<div class="layui-tabs-item" lay-id="bbb">Tab Content-2</div>
|
||||||
|
<div class="layui-tabs-item" lay-id="ccc">Tab Content-3</div>
|
||||||
|
<div class="layui-tabs-item" lay-id="ddd">Tab Content-4</div>
|
||||||
|
<div class="layui-tabs-item" lay-id="eee">Tab Content-5</div>
|
||||||
|
<div class="layui-tabs-item" lay-id="fff">Tab Content-6</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2>标签 HASH 定位</h2>
|
<h2>标签 HASH 定位</h2>
|
||||||
<div class="layui-tabs layui-hide-v" id="demoTabs-hash">
|
<div class="layui-tabs layui-hide-v" id="demoTabs-hash">
|
||||||
<ul class="layui-tabs-header">
|
<ul class="layui-tabs-header">
|
||||||
|
@ -267,6 +287,8 @@
|
||||||
}],
|
}],
|
||||||
click: function(data, othis, event) {
|
click: function(data, othis, event) {
|
||||||
var index = this.elem.index(); // 获取活动标签索引
|
var index = this.elem.index(); // 获取活动标签索引
|
||||||
|
var layid = this.elem.attr('lay-id');
|
||||||
|
|
||||||
// 新增标签操作
|
// 新增标签操作
|
||||||
if (data.action === 'add') {
|
if (data.action === 'add') {
|
||||||
// 在当前活动标签右侧新增标签页
|
// 在当前活动标签右侧新增标签页
|
||||||
|
|
|
@ -228,14 +228,13 @@ layui.define('component', function(exports) {
|
||||||
* @param {boolean} force - 是否强制删除
|
* @param {boolean} force - 是否强制删除
|
||||||
*/
|
*/
|
||||||
Class.prototype.close = function(thisHeaderItem, force) {
|
Class.prototype.close = function(thisHeaderItem, force) {
|
||||||
if(!thisHeaderItem || !thisHeaderItem[0]) return;
|
if (!thisHeaderItem || !thisHeaderItem[0]) return;
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
var options = that.config;
|
var options = that.config;
|
||||||
|
var layid = thisHeaderItem.attr('lay-id');
|
||||||
var index = thisHeaderItem.index();
|
var index = thisHeaderItem.index();
|
||||||
|
|
||||||
if (!thisHeaderItem[0]) return;
|
|
||||||
|
|
||||||
// 标签是否不可关闭
|
// 标签是否不可关闭
|
||||||
if (thisHeaderItem.attr('lay-closable') === 'false') {
|
if (thisHeaderItem.attr('lay-closable') === 'false') {
|
||||||
return;
|
return;
|
||||||
|
@ -251,7 +250,7 @@ layui.define('component', function(exports) {
|
||||||
component.CONST.MOD_NAME,
|
component.CONST.MOD_NAME,
|
||||||
'beforeClose('+ options.id +')',
|
'beforeClose('+ options.id +')',
|
||||||
$.extend(data, {
|
$.extend(data, {
|
||||||
index: thisHeaderItem.index()
|
index: index
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -271,8 +270,8 @@ layui.define('component', function(exports) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除元素
|
// 移除元素
|
||||||
|
that.findBodyItem(layid || index).remove();
|
||||||
thisHeaderItem.remove();
|
thisHeaderItem.remove();
|
||||||
that.findBodyItem(index).remove();
|
|
||||||
|
|
||||||
that.roll('auto', index);
|
that.roll('auto', index);
|
||||||
|
|
||||||
|
@ -304,14 +303,9 @@ layui.define('component', function(exports) {
|
||||||
|
|
||||||
index = index === undefined ? data.index : index;
|
index = index === undefined ? data.index : index;
|
||||||
|
|
||||||
// 将标签头 lay-closable 属性值同步到 body 项
|
var headerItem = that.findHeaderItem(index);
|
||||||
headers.each(function(i) {
|
var bodyItem = that.findBodyItem(index);
|
||||||
var othis = $(this);
|
var itemIndex = headerItem.index();
|
||||||
var closableAttr = othis.attr('lay-closable');
|
|
||||||
if (closableAttr) {
|
|
||||||
bodys.eq(i).attr('lay-closable', closableAttr);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 若当前选中标签也允许关闭,则尝试寻找不可关闭的标签并将其选中
|
// 若当前选中标签也允许关闭,则尝试寻找不可关闭的标签并将其选中
|
||||||
if (data.thisHeaderItem.attr('lay-closable') !== 'false') {
|
if (data.thisHeaderItem.attr('lay-closable') !== 'false') {
|
||||||
|
@ -323,22 +317,33 @@ layui.define('component', function(exports) {
|
||||||
} else if(prevHeader[0]) {
|
} else if(prevHeader[0]) {
|
||||||
that.change(prevHeader, true);
|
that.change(prevHeader, true);
|
||||||
}
|
}
|
||||||
} else if(index !== data.index) { // 自动切换到活动标签(功能可取消)
|
} else if(index !== data.index) { // 自动切换到活动标签
|
||||||
that.change(that.findHeaderItem(index), true);
|
that.change(headerItem, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行批量关闭标签
|
// 执行批量关闭标签
|
||||||
if (mode === 'other') { // 关闭其他标签
|
headers.each(function(i) {
|
||||||
headers.eq(index).siblings(FILTER).remove();
|
var $this = $(this);
|
||||||
bodys.eq(index).siblings(FILTER).remove();
|
var layid = $this.attr('lay-id');
|
||||||
} else if(mode === 'right') { // 关闭右侧标签
|
var bodyItem = that.findBodyItem(layid || i);
|
||||||
headers.filter(':gt('+ index +')'+ FILTER).remove();
|
|
||||||
bodys.filter(':gt('+ index +')'+ FILTER).remove();
|
// 标签是否不可关闭
|
||||||
} else { // 关闭所有标签
|
if ($this.attr('lay-closable') === 'false') {
|
||||||
headers.filter(FILTER).remove();
|
return;
|
||||||
bodys.filter(FILTER).remove();
|
}
|
||||||
}
|
|
||||||
|
// 批量关闭方式
|
||||||
|
var isCloseOther = mode === 'other' && i !== itemIndex; // 关闭其他标签
|
||||||
|
var isCloseRight = mode === 'right' && i > itemIndex; // 关闭右侧标签
|
||||||
|
var isCloseLeft = mode === 'left' && i < itemIndex; // 关闭左侧标签(不推荐)
|
||||||
|
var isCloseAll = mode === 'all'; // 关闭所有标签
|
||||||
|
|
||||||
|
if (isCloseOther || isCloseRight || isCloseLeft || isCloseAll) {
|
||||||
|
$this.remove();
|
||||||
|
bodyItem.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
that.roll('auto');
|
that.roll('auto');
|
||||||
|
|
||||||
|
@ -365,7 +370,8 @@ layui.define('component', function(exports) {
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
var options = that.config;
|
var options = that.config;
|
||||||
var index = thisHeaderItem.attr('lay-id') || thisHeaderItem.index();
|
var layid = thisHeaderItem.attr('lay-id');
|
||||||
|
var index = thisHeaderItem.index();
|
||||||
var thatA = thisHeaderItem.find('a');
|
var thatA = thisHeaderItem.find('a');
|
||||||
// 是否存在跳转链接
|
// 是否存在跳转链接
|
||||||
var isLink = typeof thatA.attr('href') === 'string' && thatA.attr('target') === '_blank';
|
var isLink = typeof thatA.attr('href') === 'string' && thatA.attr('target') === '_blank';
|
||||||
|
@ -392,7 +398,7 @@ layui.define('component', function(exports) {
|
||||||
headerItem: data.thisHeaderItem
|
headerItem: data.thisHeaderItem
|
||||||
},
|
},
|
||||||
to: {
|
to: {
|
||||||
index: thisHeaderItem.index(),
|
index: index,
|
||||||
headerItem: thisHeaderItem
|
headerItem: thisHeaderItem
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -409,7 +415,7 @@ layui.define('component', function(exports) {
|
||||||
.removeClass(component.CONST.CLASS_THIS);
|
.removeClass(component.CONST.CLASS_THIS);
|
||||||
|
|
||||||
// 执行标签内容切换
|
// 执行标签内容切换
|
||||||
that.findBodyItem(index).addClass(component.CONST.CLASS_SHOW)
|
that.findBodyItem(layid || index).addClass(component.CONST.CLASS_SHOW)
|
||||||
.siblings().removeClass(component.CONST.CLASS_SHOW);
|
.siblings().removeClass(component.CONST.CLASS_SHOW);
|
||||||
|
|
||||||
that.roll('auto', index);
|
that.roll('auto', index);
|
||||||
|
@ -467,7 +473,11 @@ layui.define('component', function(exports) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
// 不可关闭项
|
// 不可关闭项
|
||||||
if (opts.closable == false || headerItem.attr('lay-closable') === 'false') {
|
if (opts.closable == false) {
|
||||||
|
headerItem.attr('lay-closable', 'false');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerItem.attr('lay-closable') === 'false') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,30 +662,35 @@ layui.define('component', function(exports) {
|
||||||
Class.prototype.findHeaderItem = function(index) {
|
Class.prototype.findHeaderItem = function(index) {
|
||||||
var container = this.getContainer();
|
var container = this.getContainer();
|
||||||
var headerItems = container.header.items;
|
var headerItems = container.header.items;
|
||||||
var headerItem = headerItems.filter('[lay-id="'+ index +'"]');
|
|
||||||
return headerItem[0] ? headerItem : headerItems.eq(index);
|
// 根据 lay-id 匹配
|
||||||
|
if (typeof index === 'string') {
|
||||||
|
return headerItems.filter('[lay-id="'+ index +'"]');
|
||||||
|
}
|
||||||
|
|
||||||
|
return headerItems.eq(index);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取标签内容项
|
* 获取标签内容项
|
||||||
* @param {number} index - 标签索引或 lay-id
|
* @param {number|string} index - 标签索引或 lay-id
|
||||||
*/
|
*/
|
||||||
Class.prototype.findBodyItem = function(index) {
|
Class.prototype.findBodyItem = function(index) {
|
||||||
var container = this.getContainer();
|
var container = this.getContainer();
|
||||||
var bodyItems = container.body.items;
|
var bodyItems = container.body.items;
|
||||||
var bodyItem = bodyItems.filter('[lay-id="'+ index +'"]');
|
|
||||||
|
|
||||||
return bodyItem[0] ? bodyItem : function() {
|
// 根据 lay-id 匹配
|
||||||
// 若未匹配到 lay-id 对应内容项,则继续匹配对应头部项
|
if (typeof index === 'string') {
|
||||||
var headerItems = container.header.items;
|
var bodyItem = bodyItems.filter('[lay-id="'+ index +'"]');
|
||||||
var headerItem = headerItems.filter('[lay-id="'+ index +'"]');
|
return bodyItem[0] ? bodyItem : function() {
|
||||||
|
// 若未匹配到 lay-id 对应内容项,则通过对应头部项的索引匹配内容项
|
||||||
|
var headerItems = container.header.items;
|
||||||
|
var headerItem = headerItems.filter('[lay-id="'+ index +'"]');
|
||||||
|
return bodyItems.eq(headerItem.index());
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
if (headerItem[0]) {
|
return bodyItems.eq(index);
|
||||||
index = headerItem.index();
|
|
||||||
}
|
|
||||||
|
|
||||||
return bodyItems.eq(index);
|
|
||||||
}();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -734,10 +749,10 @@ layui.define('component', function(exports) {
|
||||||
* @param {('other'|'right'|'all')} [mode="all"] - 关闭方式
|
* @param {('other'|'right'|'all')} [mode="all"] - 关闭方式
|
||||||
* @param {number} index - 活动标签的索引,默认取当前选中标签的索引。一般用于标签右键事件
|
* @param {number} index - 活动标签的索引,默认取当前选中标签的索引。一般用于标签右键事件
|
||||||
*/
|
*/
|
||||||
closeMult: function(id, mode, index, force) {
|
closeMult: function(id, mode, index) {
|
||||||
var that = component.getInst(id);
|
var that = component.getInst(id);
|
||||||
if(!that) return;
|
if(!that) return;
|
||||||
that.closeMult(mode, index, force);
|
that.closeMult(mode, index);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue