mirror of https://github.com/layui/layui
feat(tabs): 支持拖拽排序
parent
ece68e117e
commit
5e2a9c4812
|
@ -99,6 +99,20 @@
|
||||||
|
|
||||||
`false`
|
`false`
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>dragSort <sup>2.12+</sup></td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
是否开启标签项拖拽排序功能
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>boolean</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
`false`
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -1315,6 +1315,8 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
|
||||||
.layui-tabs-scroll .layui-tabs-header:after{display: none; content: none; border: 0;}
|
.layui-tabs-scroll .layui-tabs-header:after{display: none; content: none; border: 0;}
|
||||||
.layui-tabs-bar .layui-icon{position: absolute; left: 0; top: 0; z-index: 3; width: 40px; height: 100%; line-height: 40px; border: 1px solid #eee; text-align: center; cursor: pointer; box-sizing: border-box; background-color: #fff; box-shadow: 2px 0 5px 0 rgb(0 0 0 / 6%);}
|
.layui-tabs-bar .layui-icon{position: absolute; left: 0; top: 0; z-index: 3; width: 40px; height: 100%; line-height: 40px; border: 1px solid #eee; text-align: center; cursor: pointer; box-sizing: border-box; background-color: #fff; box-shadow: 2px 0 5px 0 rgb(0 0 0 / 6%);}
|
||||||
.layui-tabs-bar .layui-icon-next{left: auto; right: 0; box-shadow: -2px 0 5px 0 rgb(0 0 0 / 6%);}
|
.layui-tabs-bar .layui-icon-next{left: auto; right: 0; box-shadow: -2px 0 5px 0 rgb(0 0 0 / 6%);}
|
||||||
|
.layui-tabs-dragsort-chosen:before {content: ''; height: 100%; width: 2px; background-color: #16baaa; position: absolute; top: 0; left: 0; box-sizing: border-box;}
|
||||||
|
.layui-tabs-dragsort-chosen *{ pointer-events: none;}
|
||||||
|
|
||||||
.layui-tabs-header li .layui-tabs-close{position: relative; display: inline-block; width: 16px; height: 16px; line-height: 18px; margin-left: 8px; top: 0px; text-align: center; font-size: 12px; color: #959595; border-radius: 50%; font-weight: 700; transition: all .16s; -webkit-transition: all .16s;}
|
.layui-tabs-header li .layui-tabs-close{position: relative; display: inline-block; width: 16px; height: 16px; line-height: 18px; margin-left: 8px; top: 0px; text-align: center; font-size: 12px; color: #959595; border-radius: 50%; font-weight: 700; transition: all .16s; -webkit-transition: all .16s;}
|
||||||
.layui-tabs-header li .layui-tabs-close:hover{ background-color: #ff5722; color: #fff;}
|
.layui-tabs-header li .layui-tabs-close:hover{ background-color: #ff5722; color: #fff;}
|
||||||
|
|
|
@ -25,7 +25,8 @@ layui.define('component', function(exports) {
|
||||||
CLOSE: 'layui-tabs-close',
|
CLOSE: 'layui-tabs-close',
|
||||||
BODY: 'layui-tabs-body',
|
BODY: 'layui-tabs-body',
|
||||||
ITEM: 'layui-tabs-item',
|
ITEM: 'layui-tabs-item',
|
||||||
CARD: 'layui-tabs-card'
|
CARD: 'layui-tabs-card',
|
||||||
|
DRAG_CHOSEN: 'layui-tabs-dragsort-chosen'
|
||||||
},
|
},
|
||||||
|
|
||||||
// 渲染
|
// 渲染
|
||||||
|
@ -151,11 +152,17 @@ layui.define('component', function(exports) {
|
||||||
});
|
});
|
||||||
inner.onresize = true;
|
inner.onresize = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 拖拽事件
|
||||||
|
if(options.dragSort){
|
||||||
|
that.dragSort(container.header.elem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 内部变量集
|
// 内部变量集
|
||||||
var inner = {};
|
var inner = {};
|
||||||
|
var rAF = window.requestAnimationFrame || function(fn){return setTimeout(fn, 1000 / 60)};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扩展组件原型方法
|
* 扩展组件原型方法
|
||||||
|
@ -363,9 +370,10 @@ layui.define('component', function(exports) {
|
||||||
* 切换标签
|
* 切换标签
|
||||||
* @param {Object} thisHeaderItem - 当前标签头部项元素
|
* @param {Object} thisHeaderItem - 当前标签头部项元素
|
||||||
* @param {boolean} [force=false] - 是否强制切换
|
* @param {boolean} [force=false] - 是否强制切换
|
||||||
|
* @param {boolean} [disabledScroll=false] - 是否禁用滚动
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
Class.prototype.change = function(thisHeaderItem, force) {
|
Class.prototype.change = function(thisHeaderItem, force, disabledScroll) {
|
||||||
if (!thisHeaderItem || !thisHeaderItem[0]) return;
|
if (!thisHeaderItem || !thisHeaderItem[0]) return;
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
@ -418,7 +426,10 @@ layui.define('component', function(exports) {
|
||||||
that.findBodyItem(layid || 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);
|
// 标签切换
|
||||||
|
if (!disabledScroll) {
|
||||||
|
that.roll('auto', index);
|
||||||
|
}
|
||||||
|
|
||||||
// 重新获取标签相关数据
|
// 重新获取标签相关数据
|
||||||
var data = that.data();
|
var data = that.data();
|
||||||
|
@ -714,6 +725,111 @@ layui.define('component', function(exports) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拖拽排序
|
||||||
|
* @param {jQuery} headerElem - 拖拽的头部容器元素
|
||||||
|
*/
|
||||||
|
Class.prototype.dragSort = function(headerElem) {
|
||||||
|
var that = this;
|
||||||
|
var namespace = '.lay-tabs-drag';
|
||||||
|
var container = headerElem.parent();
|
||||||
|
var scrollable = container.hasClass('layui-tabs-scroll');
|
||||||
|
var draggedElem;
|
||||||
|
var scrollWidth = headerElem.prop('scrollWidth');
|
||||||
|
var outerWidth = headerElem.outerWidth();
|
||||||
|
var scrollThreshold = 100;
|
||||||
|
|
||||||
|
var isDndElem = function(el) {
|
||||||
|
return el && el.nodeName.toLowerCase() == 'li' && !!el.getAttribute('lay-id');
|
||||||
|
};
|
||||||
|
|
||||||
|
headerElem.off(namespace);
|
||||||
|
headerElem.on('mousedown' + namespace, '>li', function() {
|
||||||
|
if(isDndElem(this)){
|
||||||
|
this.draggable = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
headerElem.on('dragstart' + namespace, function(e) {
|
||||||
|
e.originalEvent.dataTransfer.effectAllowed = 'move';
|
||||||
|
draggedElem = $(e.target);
|
||||||
|
that.change(draggedElem, false, true);
|
||||||
|
});
|
||||||
|
headerElem.on('dragenter' + namespace, function(e) {
|
||||||
|
if(isDndElem(e.target)) {
|
||||||
|
$(e.target).addClass(component.CONST.DRAG_CHOSEN);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
headerElem.on("dragover" + namespace, function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.originalEvent.dataTransfer.dropEffect = "move";
|
||||||
|
|
||||||
|
// 拖拽边缘滚动
|
||||||
|
if (scrollable) {
|
||||||
|
var tabLeft = headerElem.data("left") || 0;
|
||||||
|
var containerRect = container[0].getBoundingClientRect();
|
||||||
|
var step = 200;
|
||||||
|
var rAFStep = 5;
|
||||||
|
var isScrollLeft = e.clientX - containerRect.left < scrollThreshold;
|
||||||
|
var isScrollRight = containerRect.right - e.clientX < scrollThreshold;
|
||||||
|
|
||||||
|
if (!isScrollLeft && !isScrollRight) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cb = function () {
|
||||||
|
if (step > 0) {
|
||||||
|
step -= rAFStep;
|
||||||
|
if (isScrollLeft) {
|
||||||
|
tabLeft += rAFStep;
|
||||||
|
} else if (isScrollRight) {
|
||||||
|
tabLeft += -rAFStep;
|
||||||
|
}
|
||||||
|
if (tabLeft > 0) {
|
||||||
|
tabLeft = 0;
|
||||||
|
} else if (tabLeft < outerWidth - scrollWidth) {
|
||||||
|
tabLeft = outerWidth - scrollWidth;
|
||||||
|
}
|
||||||
|
headerElem.css("left", tabLeft).data("left", tabLeft);
|
||||||
|
rAF(cb);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
rAF(cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
headerElem.on('dragleave' + namespace, function(e) {
|
||||||
|
if(isDndElem(e.target)) {
|
||||||
|
$(e.target).removeClass(component.CONST.DRAG_CHOSEN);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
headerElem.on('drop' + namespace, function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (isDndElem(e.target)) {
|
||||||
|
var dropTargetElem = $(e.target);
|
||||||
|
dropTargetElem.removeClass(component.CONST.DRAG_CHOSEN);
|
||||||
|
var dragIndex = that.data().thisHeaderItem.index();
|
||||||
|
var dropIndex = dropTargetElem.index();
|
||||||
|
|
||||||
|
if(dragIndex > dropIndex) {
|
||||||
|
dropTargetElem.before(draggedElem);
|
||||||
|
} else {
|
||||||
|
dropTargetElem.after(draggedElem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
headerElem.on('dragend' + namespace, function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
draggedElem = null;
|
||||||
|
|
||||||
|
var data = that.data();
|
||||||
|
layui.event.call(
|
||||||
|
data.thisHeaderItem[0],
|
||||||
|
component.CONST.MOD_NAME,
|
||||||
|
'dragend(' + that.config.id +')',
|
||||||
|
that.data()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 扩展组件接口
|
// 扩展组件接口
|
||||||
$.extend(component, {
|
$.extend(component, {
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue