Commit 459f426a authored by zhangwenshuai's avatar zhangwenshuai

增加右侧拖拽

parent b60f523c
...@@ -19,23 +19,36 @@ const DragSorted = (props: any) => { ...@@ -19,23 +19,36 @@ const DragSorted = (props: any) => {
const divider: any = document.querySelector('#divider'); const divider: any = document.querySelector('#divider');
// 左侧固定列分割线 // 左侧固定列分割线
const leftFixedHandleWrap: any = document.querySelector('#leftFixedHandleWrap'); const leftFixedHandleWrap: any = document.querySelector('#leftFixedHandleWrap');
const rightFixedHandleWrap: any = document.querySelector('#rightFixedHandleWrap');
// 监听鼠标移动 // 监听鼠标移动
const onMouseMove = useCallback((e) => { const onMouseMove = useCallback((e) => {
const tableRect = container.getBoundingClientRect(); const tableRect = container.getBoundingClientRect();
const detaX = columnCopyDiv.getAttribute('data-deta-x'); const detaX = columnCopyDiv.getAttribute('data-deta-x');
// 所有列 // 所有列
const draggableColumns = document.querySelectorAll('.draggableColumn'); const draggableColumns = document.querySelectorAll('.draggableColumn');
const leftFixedHandleWrapRect = leftFixedHandleWrap.getBoundingClientRect(); const leftFixedHandleWrapRectX = (leftFixedHandleWrap && leftFixedHandleWrap.getBoundingClientRect().x) || 0;
const rightFixedHandleWrapRectX = (rightFixedHandleWrap && rightFixedHandleWrap.getBoundingClientRect().x) || tableRect.right;
const columnCopyDivRect = columnCopyDiv.getBoundingClientRect(); const columnCopyDivRect = columnCopyDiv.getBoundingClientRect();
const columnCopyDivWidth = columnCopyDivRect.width; const columnCopyDivWidth = columnCopyDivRect.width;
const columnCopyDivX = columnCopyDivRect.x; const columnCopyDivX = columnCopyDivRect.x;
// 影子div中间点的x坐标 // 影子div中间点的x坐标
const columnCopyDivMid = columnCopyDivX + columnCopyDivWidth / 2; const columnCopyDivMid = columnCopyDivX + columnCopyDivWidth / 2;
const left = e.clientX - tableRect.x - Number(detaX);
// 影子div随鼠标移动
// 鼠标在左侧固定列与右侧固定列之间有效
if (e.clientX > leftFixedHandleWrapRectX && e.clientX < rightFixedHandleWrapRectX) {
columnCopyDiv.style.left = `${left}px`;
}
draggableColumns.forEach((dom) => { draggableColumns.forEach((dom) => {
const domRect = dom.getBoundingClientRect(); const domRect = dom.getBoundingClientRect();
if (columnCopyDivMid > domRect.x && columnCopyDivMid < domRect.x + domRect.width) { // 当前节点在左侧固定列与右侧固定列之间有效
if (
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`;
// 收集投放目标的信息 // 收集投放目标的信息
...@@ -46,24 +59,20 @@ const DragSorted = (props: any) => { ...@@ -46,24 +59,20 @@ const DragSorted = (props: any) => {
} }
}); });
const left = e.clientX - tableRect.x - Number(detaX);
// 影子div随鼠标移动
columnCopyDiv.style.left = `${left}px`;
if (typeof onScroll === 'function') { if (typeof onScroll === 'function') {
let dir = ''; let dir = '';
let step = 10; let step = 10;
// 设置鼠标超出表格左右两侧时的滚动事件 // 设置鼠标超出表格左右固定列两侧时的滚动事件
if (e.clientX > tableRect.right - 30) { if (columnCopyDivX + columnCopyDivWidth > rightFixedHandleWrapRectX - 50) {
dir = 'right'; dir = 'right';
step = 100; step = 100;
} else if (e.clientX > tableRect.right - 100) { } else if (columnCopyDivX + columnCopyDivWidth > rightFixedHandleWrapRectX - 100) {
dir = 'right'; dir = 'right';
step = 10; step = 30;
} else if (e.clientX < leftFixedHandleWrapRect.x + 100) { } else if (columnCopyDivX < leftFixedHandleWrapRectX + 100) {
dir = 'left'; dir = 'left';
step = 10; step = 30;
} else if (e.clientX < leftFixedHandleWrapRect.x + 30) { } else if (columnCopyDivX < leftFixedHandleWrapRectX + 50) {
dir = 'left'; dir = 'left';
step = 100; step = 100;
} else { } else {
......
import React from 'react';
import { ResizableBox } from 'react-resizable';
import styles from './DragFixed.less';
const DragFixed = (props: any) => {
const {
initLeft,
initTop,
onResizeStart,
tableWidth,
showColumns,
columnWidth,
columns,
onResizeStop,
scrollbarWidth,
} = props;
// 表格
const container: any = document.querySelector('#tableContainer');
// 滑块wrap
const handleWrap: any = document.querySelector('#rightFixedHandleWrap');
// 滑块
const handle: any = document.querySelector('#rightFixedHandle');
// 分割线wrap
const dividerWrap: any = document.querySelector('#dividerWrap');
// 分割线
const divider: any = document.querySelector('#divider');
const onMouseEnterWrap = (e: any) => {
// 滑块wrap添加hovered样式
handleWrap.classList.add(styles.hovered);
// 滑块初始化位置,显示
handle.style.top = `${e.clientY}px`;
handle.style.opacity = 1;
};
const onMouseMoveWrap = (e: any) => {
// 滑块位置跟随鼠标上下移动
handle.style.top = `${e.clientY}px`;
};
const onMouseLeaveWrap = () => {
// 滑块wrap移除hovered样式
handleWrap.classList.remove(styles.hovered);
// 滑块隐藏
handle.style.opacity = 0;
};
const onResizeStartHandle = (e: any) => {
if (typeof onResizeStart === 'function') {
onResizeStart();
}
const originLeft = container.getBoundingClientRect().x || 0;
handleWrap.style.top = 0;
handleWrap.style.left = `${e.x - originLeft}px`;
};
const onResizeHandle = (e: any) => {
const containerRect: any = container.getBoundingClientRect();
let inTableRight = containerRect.right - e.x;
// left不能超过表格一半宽度
if (inTableRight > tableWidth / 2) {
inTableRight = tableWidth / 2;
}
let fixedWidth = 0;
let index = 0;
// 计算固定列宽度及索引
for (let i = showColumns.length - 1; i >= 0; i--) {
fixedWidth += showColumns[i].width || columnWidth;
if (fixedWidth > inTableRight) {
index = i;
break;
}
}
let rightHandleLeft = fixedWidth - (showColumns[index].width || columnWidth);
// if (inTableRight > fixedWidth - (showColumns[index].width || columnWidth) / 2) {
// // left位于当前列中间偏右
// rightHandleLeft = fixedWidth;
// } else {
// // left位于当前列中间偏左
// rightHandleLeft = fixedWidth - (showColumns[index].width || columnWidth);
// }
// 拖动时显示分割线
dividerWrap.style.display = 'block';
// 分割线取列的边侧位置
divider.style.left = `${containerRect.width - scrollbarWidth - rightHandleLeft}px`;
// 拖动线取鼠标位置
handleWrap.style.left = `${containerRect.width - scrollbarWidth - inTableRight}px`;
// 滑动过程中滑块始终显示
// 滑块wrap添加hovered样式
handleWrap.classList.add(styles.hovered);
// 滑块初始化位置,显示
handle.style.opacity = 1;
};
const onResizeStopHandle = () => {
// 当前固定列宽度为分割线的left
const fixedWidth: string = divider.style.left;
// 样式转数值
const fixedWidthNum: string = fixedWidth.slice(0, -2);
// 分隔线wrap隐藏
dividerWrap.style.display = 'none';
// 滑块wrap移除hovered样式
handleWrap.classList.remove(styles.hovered);
handleWrap.style.top = `${initTop}px`;
handleWrap.style.left = fixedWidth;
// 滑块隐藏
handle.style.opacity = 0;
let leftFixedWidth = 0;
const fixedCol: any = {};
// 计算获取固定列
for (let i = showColumns.length - 1; i >= 0; i--) {
leftFixedWidth += showColumns[i].width || columnWidth;
if (leftFixedWidth <= tableWidth + scrollbarWidth - Number(fixedWidthNum)) {
fixedCol[showColumns[i].columnName] = 1;
} else {
break;
}
}
const newColumns: any = [];
// 为固定列增加fixed属性
columns.map((item: any) => {
if (fixedCol[item.columnName] === 1) {
item.fixed = 'right';
} else {
if (item.fixed === 'right') {
item.fixed = '';
}
}
newColumns.push(item);
});
if (typeof onResizeStop === 'function') {
onResizeStop({ columns: newColumns });
}
};
return (
<div
id="rightFixedHandleWrap"
className={styles.leftFixedHandleWrap}
style={{
left: `${initLeft}px`,
top: `${initTop}px`,
}}
onMouseEnter={onMouseEnterWrap}
onMouseMove={onMouseMoveWrap}
onMouseLeave={onMouseLeaveWrap}
>
<ResizableBox
handle={
<span
id="rightFixedHandle"
className={styles.leftFixedHandle}
onClick={(e) => {
e.stopPropagation();
}}
/>
}
onResizeStart={onResizeStartHandle}
onResize={onResizeHandle}
onResizeStop={onResizeStopHandle}
draggableOpts={{ enableUserSelectHack: false }}
/>
</div>
);
};
export default DragFixed;
...@@ -141,7 +141,7 @@ ...@@ -141,7 +141,7 @@
top: 0; top: 0;
bottom: 0; bottom: 0;
background: rgba(0,0,0,0.3); background: rgba(0,0,0,0.3);
z-index: 5; //z-index: 5;
//pointer-events: none; //pointer-events: none;
display: none; display: none;
cursor: grab; cursor: grab;
......
This diff is collapsed.
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