Commit cee48c4a authored by 李晓静's avatar 李晓静
parents 2bcf4c9a 69545408
...@@ -17,11 +17,17 @@ const DragSorted = (props: any) => { ...@@ -17,11 +17,17 @@ const DragSorted = (props: any) => {
position, position,
columnChsName, columnChsName,
} = props; } = props;
if (!canSorted || position === 'left' || position === 'right') { if (!canSorted) {
return <div className={s.sortedWrap}>{props.children}</div>; return <div className={s.sortedWrap}>{props.children}</div>;
} }
// 长按计时器 // 按下鼠标
const timer: any = useRef(null); const pressed: any = useRef(false);
// copyDiv显示
const copyDivShow: any = useRef(false);
// 拖动列
const dragCol: any = useRef();
// 放置列
const dropCol: any = useRef();
// 表格滚动计时器 // 表格滚动计时器
const timerInterval: any = useRef(null); const timerInterval: any = useRef(null);
// 表格 // 表格
...@@ -37,6 +43,15 @@ const DragSorted = (props: any) => { ...@@ -37,6 +43,15 @@ const DragSorted = (props: any) => {
const rightFixedHandleWrap: any = document.querySelector('#rightFixedHandleWrap'); const rightFixedHandleWrap: any = document.querySelector('#rightFixedHandleWrap');
// 监听鼠标移动 // 监听鼠标移动
const onMouseMove = useCallback((e) => { const onMouseMove = useCallback((e) => {
if (!pressed.current) {
// 移除全局事件
document.body.removeEventListener('mousemove', onMouseMove, false);
document.body.removeEventListener('mouseup', onMouseUp, false);
return;
}
if (!copyDivShow.current) {
initCopyDiv(e);
}
const tableRect = container.getBoundingClientRect(); const tableRect = container.getBoundingClientRect();
const detaX = columnCopyDiv.getAttribute('data-deta-x'); const detaX = columnCopyDiv.getAttribute('data-deta-x');
// 所有列 // 所有列
...@@ -45,33 +60,33 @@ const DragSorted = (props: any) => { ...@@ -45,33 +60,33 @@ const DragSorted = (props: any) => {
const rightFixedHandleWrapRectX = const rightFixedHandleWrapRectX =
(rightFixedHandleWrap && rightFixedHandleWrap.getBoundingClientRect().x) || tableRect.right; (rightFixedHandleWrap && rightFixedHandleWrap.getBoundingClientRect().x) || tableRect.right;
const columnCopyDivRect = columnCopyDiv.getBoundingClientRect();
const columnCopyDivWidth = columnCopyDivRect.width;
const columnCopyDivX = columnCopyDivRect.x;
// 影子div中间点的x坐标
const columnCopyDivMid = columnCopyDivX + columnCopyDivWidth / 2;
const left = e.clientX - tableRect.x - Number(detaX); const left = e.clientX - tableRect.x - Number(detaX);
// 影子div随鼠标移动 // 影子div随鼠标移动
// 鼠标在左侧固定列与右侧固定列之间有效 // 鼠标在左侧固定列与右侧固定列之间有效
if (e.clientX > leftFixedHandleWrapRectX && e.clientX < rightFixedHandleWrapRectX) { if (e.clientX > tableRect.x && e.clientX < tableRect.right) {
columnCopyDiv.style.left = `${left}px`; columnCopyDiv.style.left = `${left}px`;
} }
draggableColumns.forEach((dom) => { draggableColumns.forEach((dom) => {
const domRect = dom.getBoundingClientRect(); const domRect = dom.getBoundingClientRect();
// 当前节点在左侧固定列与右侧固定列之间有效 // 当前节点在左侧固定列与右侧固定列之间有效
if ( if (e.clientX > domRect.x && e.clientX < domRect.x + domRect.width / 2) {
domRect.x > leftFixedHandleWrapRectX &&
domRect.x < rightFixedHandleWrapRectX &&
columnCopyDivMid > domRect.x &&
columnCopyDivMid < domRect.x + domRect.width
) {
// 影子div中点在投放目标中 // 影子div中点在投放目标中
divider.style.left = `${domRect.x - tableRect.x}px`; divider.style.left = `${domRect.x - tableRect.x}px`;
// 收集投放目标的信息 // 收集投放目标的信息
const dropColumn = dom.getAttribute('data-column-name') || ''; const dropColumn = dom.getAttribute('data-column-name') || '';
const dropColumnOrder = dom.getAttribute('data-column-order') || ''; dropCol.current = {
divider.setAttribute('data-drop-column', dropColumn); columnName: dropColumn,
divider.setAttribute('data-drop-order', dropColumnOrder); move: -1,
};
} else if (e.clientX > domRect.x + domRect.width / 2 && e.clientX < domRect.x + domRect.width) {
// 影子div中点在投放目标中
divider.style.left = `${domRect.x - tableRect.x + domRect.width}px`;
// 收集投放目标的信息
const dropColumn = dom.getAttribute('data-column-name') || '';
dropCol.current = {
columnName: dropColumn,
move: 1,
};
} }
}); });
...@@ -79,16 +94,16 @@ const DragSorted = (props: any) => { ...@@ -79,16 +94,16 @@ const DragSorted = (props: any) => {
let dir = ''; let dir = '';
let step = 10; let step = 10;
// 设置鼠标超出表格左右固定列两侧时的滚动事件 // 设置鼠标超出表格左右固定列两侧时的滚动事件
if (columnCopyDivX + columnCopyDivWidth > rightFixedHandleWrapRectX - 50) { if (e.clientX > rightFixedHandleWrapRectX - 50) {
dir = 'right'; dir = 'right';
step = 100; step = 100;
} else if (columnCopyDivX + columnCopyDivWidth > rightFixedHandleWrapRectX - 100) { } else if (e.clientX > rightFixedHandleWrapRectX - 100) {
dir = 'right'; dir = 'right';
step = 30; step = 30;
} else if (columnCopyDivX < leftFixedHandleWrapRectX + 100) { } else if (e.clientX < leftFixedHandleWrapRectX + 100) {
dir = 'left'; dir = 'left';
step = 30; step = 30;
} else if (columnCopyDivX < leftFixedHandleWrapRectX + 50) { } else if (e.clientX < leftFixedHandleWrapRectX + 50) {
dir = 'left'; dir = 'left';
step = 100; step = 100;
} else { } else {
...@@ -114,81 +129,48 @@ const DragSorted = (props: any) => { ...@@ -114,81 +129,48 @@ const DragSorted = (props: any) => {
}, []); }, []);
// 监听鼠标抬起 // 监听鼠标抬起
const onMouseUp = useCallback(() => { const onMouseUp = useCallback(() => {
// 清空计时器
if (timer.current) {
clearTimeout(timer.current);
timer.current = null;
}
if (timerInterval.current) {
clearInterval(timerInterval.current);
timerInterval.current = null;
}
// 移除全局事件
document.body.removeEventListener('mousemove', onMouseMove, false);
document.body.removeEventListener('mouseup', onMouseUp, false);
// 停止拖动时隐藏影子div
columnCopyDiv.style.display = 'none';
dividerWrap.style.display = 'none';
// 获取分割线上挂载的拖动列和投放列信息 // 获取分割线上挂载的拖动列和投放列信息
const dragColumn = divider.getAttribute('data-drag-column'); const dragColumn = dragCol.current && dragCol.current.columnName;
const dragColumnOrder = divider.getAttribute('data-drag-order'); const dropColumn = dropCol.current && dropCol.current.columnName;
const dropColumn = divider.getAttribute('data-drop-column'); const dropMove = dropCol.current && dropCol.current.move;
const dropColumnOrder = divider.getAttribute('data-drop-order'); // 清理操作
clean();
// 没有列信息 // 没有列信息
if (!dragColumn || !dropColumn) { if (!dragColumn || !dropColumn) {
return; return;
} }
// 没有拖动
if (Number(dropColumnOrder) === Number(dragColumnOrder)) {
return;
}
// 拖动没有产生移动
if (Number(dropColumnOrder) - Number(dragColumnOrder) === 1) {
return;
}
// 拖动回调 // 拖动回调
const newColumns: any[] = []; let newColumns: any[] = [...columns];
// 从右往左拖 const dragIndex = newColumns.findIndex((item) => item.columnName === dragColumn);
if (Number(dragColumnOrder) > Number(dropColumnOrder)) { const dragObj = newColumns[dragIndex];
// columns已排序 newColumns.splice(dragIndex, 1);
columns.map((item: any, i: number) => { const dropIndex = newColumns.findIndex((item) => item.columnName === dropColumn);
if (item.orderNo >= Number(dropColumnOrder) && item.orderNo <= Number(dragColumnOrder)) { newColumns.splice(dropIndex + dropMove + 1, 0, dragObj);
if (item.columnName === dragColumn) { const lenLeft = newColumns.filter((item) => item.fixed === 'left').length;
newColumns.push({ const lenRight = newColumns.filter((item) => item.fixed === 'right').length;
...item, const len = newColumns.length;
orderNo: Number(dropColumnOrder), newColumns = newColumns.map((item: any, i: number) => {
}); if (i < lenLeft) {
} else { return {
newColumns.push({ ...item,
...item, orderNo: i + 1,
orderNo: columns[i + 1].orderNo, fixed: 'left',
}); };
} }
} else { if (i >= len - lenRight) {
newColumns.push(item); return {
} ...item,
}); orderNo: i + 1,
} else { fixed: 'right',
// 从左往右拖 };
const index = columns.findIndex((item: any) => { }
return item.columnName === dropColumn; return {
}); ...item,
columns.map((item: any, i: number) => { orderNo: i + 1,
if (item.columnName === dragColumn) { fixed: '',
newColumns.push({ };
...item, });
orderNo: columns[index - 1].orderNo,
});
} else if (item.orderNo > Number(dragColumnOrder) && item.orderNo < Number(dropColumnOrder)) {
newColumns.push({
...item,
orderNo: columns[i - 1].orderNo,
});
} else {
newColumns.push(item);
}
});
}
if (cachedFeAttr) { if (cachedFeAttr) {
const cachedCols = getCache({ tableId }); const cachedCols = getCache({ tableId });
if (cachedCols) { if (cachedCols) {
...@@ -196,6 +178,7 @@ const DragSorted = (props: any) => { ...@@ -196,6 +178,7 @@ const DragSorted = (props: any) => {
cachedCols[item.columnName] = { cachedCols[item.columnName] = {
...cachedCols[item.columnName], ...cachedCols[item.columnName],
orderNo: item.orderNo, orderNo: item.orderNo,
fixed: item.fixed,
}; };
}); });
saveCache({ tableId, data: cachedCols }); saveCache({ tableId, data: cachedCols });
...@@ -215,40 +198,62 @@ const DragSorted = (props: any) => { ...@@ -215,40 +198,62 @@ const DragSorted = (props: any) => {
if (e.button !== 0) { if (e.button !== 0) {
return; return;
} }
// 鼠标按下标记
pressed.current = true;
// 记录拖动列
dragCol.current = {
columnName,
orderNo,
};
// 全局添加监听鼠标移动和松开事件
document.body.addEventListener('mousemove', onMouseMove, false);
document.body.addEventListener('mouseup', onMouseUp, false);
},
[onMouseMove, onMouseUp],
);
// 初始化影子div位置
const initCopyDiv = useCallback(
(e) => {
// 表格初始位置x点 // 表格初始位置x点
const originLeft = container.getBoundingClientRect().x || 0; const originLeft = container.getBoundingClientRect().x || 0;
// 拖动列矩形 // 拖动列矩形
const targetRect = e.currentTarget.getBoundingClientRect(); const targetRect = e.target.offsetParent.getBoundingClientRect();
const curX = e.clientX; const curX = e.clientX;
// 500ms长按事件,表示想要拖拽 // 影子div显示
timer.current = setTimeout(() => { columnCopyDiv.style.display = 'block';
// 影子div显示 // 影子div初始x位置=拖动列x点-表格x点
columnCopyDiv.style.display = 'block'; columnCopyDiv.style.left = `${targetRect.x - originLeft}px`;
// 影子div初始x位置=拖动列x点-表格x点 // 影子div宽度=拖动列宽度
columnCopyDiv.style.left = `${targetRect.x - originLeft}px`; columnCopyDiv.style.width = `${targetRect.width}px`;
// 影子div宽度=拖动列宽度 columnCopyDiv.innerText = columnChsName;
columnCopyDiv.style.width = `${targetRect.width}px`; // 鼠标x点与拖动列x点之间的距离(记录下来方便后续使用)
columnCopyDiv.innerText = columnChsName; const detaX = curX - targetRect.x;
// 鼠标x点与拖动列x点之间的距离(记录下来方便后续使用) columnCopyDiv.setAttribute('data-deta-x', String(detaX));
const detaX = curX - targetRect.x; // 分割线初始位置为当前列
columnCopyDiv.setAttribute('data-deta-x', String(detaX)); divider.style.left = `${targetRect.x - originLeft}px`;
// 分割线初始位置为当前列 dividerWrap.style.display = 'block';
divider.style.left = `${targetRect.x - originLeft}px`; copyDivShow.current = true;
dividerWrap.style.display = 'block';
// 给分割线设置拖动列信息,移除投放列信息
divider.setAttribute('data-drag-column', columnName);
divider.setAttribute('data-drag-order', orderNo);
divider.removeAttribute('data-drop-column');
divider.removeAttribute('data-drop-order');
// 全局添加监听鼠标移动和松开事件
document.body.addEventListener('mousemove', onMouseMove, false);
document.body.addEventListener('mouseup', onMouseUp, false);
}, 500);
// 阻止默认行为
e.preventDefault();
}, },
[columnName, orderNo, onMouseMove, onMouseUp], [columnName, orderNo],
); );
const clean = useCallback(() => {
// 鼠标松开
pressed.current = false;
// 清空计时器
if (timerInterval.current) {
clearInterval(timerInterval.current);
timerInterval.current = null;
}
// 移除全局事件
document.body.removeEventListener('mousemove', onMouseMove, false);
document.body.removeEventListener('mouseup', onMouseUp, false);
// 停止拖动时隐藏影子div
columnCopyDiv.style.display = 'none';
dividerWrap.style.display = 'none';
copyDivShow.current = false;
dragCol.current = null;
dropCol.current = null;
}, [onMouseMove, onMouseUp]);
return ( return (
<div <div
......
...@@ -109,4 +109,5 @@ ...@@ -109,4 +109,5 @@
cursor: grab; cursor: grab;
text-align: center; text-align: center;
padding-top: @paddingSmX; padding-top: @paddingSmX;
z-index: 2;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment