Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
submodule
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
web_component
submodule
Commits
e9dc8a33
Commit
e9dc8a33
authored
Jul 11, 2020
by
zhangwenshuai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完善拖拽列功能
parent
49fb06fc
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
150 additions
and
97 deletions
+150
-97
DragSorted.tsx
components/apolloTable/component/DragSorted.tsx
+144
-93
Table.less
components/apolloTable/component/Table.less
+3
-2
Table.tsx
components/apolloTable/component/Table.tsx
+3
-2
No files found.
components/apolloTable/component/DragSorted.tsx
View file @
e9dc8a33
import
React
,
{
useCallback
}
from
'react'
;
import
React
,
{
useCallback
,
useRef
}
from
'react'
;
import
classNames
from
'classnames'
;
import
classNames
from
'classnames'
;
import
s
from
'./DragSorted.less'
;
const
DragSorted
=
(
props
:
any
)
=>
{
const
DragSorted
=
(
props
:
any
)
=>
{
const
{
className
,
style
,
columnConfig
,
onDropFinish
,
onScroll
}
=
props
;
const
{
className
,
style
,
columnName
,
orderNo
,
onDropFinish
,
onScroll
,
}
=
props
;
// 长按计时器
const
timer
:
any
=
useRef
(
null
);
// 表格滚动计时器
const
timerInterval
:
any
=
useRef
(
null
);
// 表格
// 表格
const
container
:
any
=
document
.
querySelector
(
'#tableContainer'
);
const
container
:
any
=
document
.
querySelector
(
'#tableContainer'
);
// 拖拽列时的影子div
// 拖拽列时的影子div
...
@@ -14,115 +19,161 @@ const DragSorted = (props: any) => {
...
@@ -14,115 +19,161 @@ 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
onMouseMove
=
useCallback
((
e
)
=>
{
const
onDragStart
=
useCallback
((
e
)
=>
{
// 表格初始位置x点
const
originLeft
=
container
.
getBoundingClientRect
().
x
||
0
;
// 拖动列矩形
const
targetRect
=
e
.
target
.
getBoundingClientRect
();
// 影子div显示
columnCopyDiv
.
style
.
display
=
'block'
;
// 影子div初始x位置=拖动列x点-表格x点
columnCopyDiv
.
style
.
left
=
`
${
targetRect
.
x
-
originLeft
}
px`
;
// 影子div宽度=拖动列宽度
columnCopyDiv
.
style
.
width
=
`
${
targetRect
.
width
}
px`
;
// 鼠标x点与拖动列x点之间的距离(记录下来方便后续使用)
const
detaX
=
e
.
clientX
-
targetRect
.
x
;
columnCopyDiv
.
setAttribute
(
'data-deta-x'
,
detaX
);
// 将拖动列信息加入拖拽事件dataTransfer中,方便后续使用
e
.
dataTransfer
.
setData
(
'dragColumn'
,
JSON
.
stringify
(
columnConfig
));
// debugger
divider
.
style
.
left
=
`
${
targetRect
.
x
-
originLeft
}
px`
;
dividerWrap
.
style
.
display
=
'block'
;
},
[
columnConfig
.
columnName
]);
// 拖动中
const
onDragUpdate
=
useCallback
((
e
)
=>
{
// 拖动列矩形
const
targetRect
=
e
.
target
.
getBoundingClientRect
();
const
tableRect
=
container
.
getBoundingClientRect
();
const
tableRect
=
container
.
getBoundingClientRect
();
const
detaX
=
columnCopyDiv
.
getAttribute
(
'data-deta-x'
);
const
detaX
=
columnCopyDiv
.
getAttribute
(
'data-deta-x'
);
const
left
=
e
.
clientX
-
tableRect
.
x
-
detaX
;
// 所有列
console
.
log
(
'left: '
,
left
);
const
draggableColumns
=
document
.
querySelectorAll
(
'.draggableColumn'
);
// 影子div随鼠标移动
columnCopyDiv
.
style
.
left
=
`
${
left
}
px`
;
},
[]);
// 停止拖动
const
onDragEnd
=
useCallback
((
e
)
=>
{
// 停止拖动时隐藏影子div
columnCopyDiv
.
style
.
display
=
'none'
;
dividerWrap
.
style
.
display
=
'none'
;
console
.
log
(
'stop: '
);
},
[]);
// ? 投放目标事件
// 在投放目标中移动
const
onDragOver
=
useCallback
((
e
)
=>
{
const
tableRect
=
container
.
getBoundingClientRect
();
const
targetRect
=
e
.
target
.
getBoundingClientRect
();
const
columnCopyDivRect
=
columnCopyDiv
.
getBoundingClientRect
();
const
leftFixedHandleWrapRect
=
leftFixedHandleWrap
.
getBoundingClientRect
();
const
leftFixedHandleWrapRect
=
leftFixedHandleWrap
.
getBoundingClientRect
();
const
targetWidth
=
targetRect
.
width
;
const
targetX
=
targetRect
.
x
;
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
;
if
(
columnCopyDivMid
>
targetX
&&
columnCopyDivMid
<
targetX
+
targetWidth
)
{
// 影子div中点在投放目标中
draggableColumns
.
forEach
((
dom
)
=>
{
divider
.
style
.
left
=
`
${
targetRect
.
x
-
tableRect
.
x
}
px`
;
const
domRect
=
dom
.
getBoundingClientRect
();
}
if
(
columnCopyDivMid
>
domRect
.
x
&&
columnCopyDivMid
<
domRect
.
x
+
domRect
.
width
)
{
// 影子div中点在投放目标中
divider
.
style
.
left
=
`
${
domRect
.
x
-
tableRect
.
x
}
px`
;
// 收集投放目标的信息
const
dropColumn
=
dom
.
getAttribute
(
'data-column-name'
)
||
''
;
const
dropColumnOrder
=
dom
.
getAttribute
(
'data-column-order'
)
||
''
;
divider
.
setAttribute
(
'data-drop-column'
,
dropColumn
);
divider
.
setAttribute
(
'data-drop-order'
,
dropColumnOrder
);
}
});
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
step
=
10
;
// 设置鼠标超出表格左右两侧时的滚动事件
if
(
e
.
clientX
>
tableRect
.
right
-
30
)
{
if
(
e
.
clientX
>
tableRect
.
right
-
30
)
{
onScroll
(
'right'
,
100
);
dir
=
'right'
;
step
=
100
;
}
else
if
(
e
.
clientX
>
tableRect
.
right
-
100
)
{
}
else
if
(
e
.
clientX
>
tableRect
.
right
-
100
)
{
onScroll
(
'right'
,
10
);
dir
=
'right'
;
step
=
10
;
}
else
if
(
e
.
clientX
<
leftFixedHandleWrapRect
.
x
+
100
)
{
}
else
if
(
e
.
clientX
<
leftFixedHandleWrapRect
.
x
+
100
)
{
onScroll
(
'left'
,
10
);
dir
=
'left'
;
step
=
10
;
}
else
if
(
e
.
clientX
<
leftFixedHandleWrapRect
.
x
+
30
)
{
}
else
if
(
e
.
clientX
<
leftFixedHandleWrapRect
.
x
+
30
)
{
onScroll
(
'left'
,
100
);
dir
=
'left'
;
step
=
100
;
}
else
{
dir
=
''
;
}
}
}
if
(
dir
)
{
// 需要滚动,如果已有计时器,先清除再重新设置计时器
// 元素默认是不能够投放,需在目标元素的dragover事件中取消默认事件
if
(
timerInterval
.
current
)
{
var
event
=
e
||
window
.
event
;
clearInterval
(
timerInterval
.
current
);
event
.
preventDefault
()
}
},
[]);
timerInterval
.
current
=
setInterval
(()
=>
{
// 在投放目标中松开鼠标
onScroll
(
dir
,
step
);
const
onDrop
=
useCallback
((
e
)
=>
{
},
350
);
const
targetRect
=
e
.
target
.
getBoundingClientRect
();
}
else
{
const
columnCopyDivRect
=
columnCopyDiv
.
getBoundingClientRect
();
// 需要停止,清除已有计时器
const
targetWidth
=
targetRect
.
width
;
// eslint-disable-next-line no-lonely-if
const
targetX
=
targetRect
.
x
;
if
(
timerInterval
.
current
)
{
const
columnCopyDivWidth
=
columnCopyDivRect
.
width
;
clearInterval
(
timerInterval
.
current
);
const
columnCopyDivX
=
columnCopyDivRect
.
x
;
timerInterval
.
current
=
null
;
// 影子div中间点的x坐标
const
columnCopyDivMid
=
columnCopyDivX
+
(
columnCopyDivWidth
/
2
);
if
(
columnCopyDivMid
>
targetX
&&
columnCopyDivMid
<
targetX
+
targetWidth
)
{
// 影子div中点在投放目标中
try
{
const
dragColumn
=
JSON
.
parse
(
e
.
dataTransfer
.
getData
(
'dragColumn'
));
const
dropColumn
=
columnConfig
;
if
(
typeof
onDropFinish
===
'function'
)
{
onDropFinish
(
dragColumn
,
dropColumn
);
}
}
}
catch
(
e
)
{
console
.
error
(
'json解析失败'
)
}
}
}
}
},
[
columnConfig
.
columnName
]);
},
[]);
// 监听鼠标抬起
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
dragColumnOrder
=
divider
.
getAttribute
(
'data-drag-order'
);
const
dropColumn
=
divider
.
getAttribute
(
'data-drop-column'
);
const
dropColumnOrder
=
divider
.
getAttribute
(
'data-drop-order'
);
// 没有列信息
if
(
!
dragColumn
||
!
dropColumn
)
{
return
;
}
// 没有拖动
if
(
Number
(
dropColumnOrder
)
===
Number
(
dragColumnOrder
))
{
return
;
}
// 拖动没有产生移动
if
(
Number
(
dropColumnOrder
)
-
Number
(
dragColumnOrder
)
===
1
)
{
return
;
}
// 拖动回调
if
(
typeof
onDropFinish
===
'function'
)
{
onDropFinish
(
{
columnName
:
dragColumn
,
orderNo
:
Number
(
dragColumnOrder
)
},
{
columnName
:
dropColumn
,
orderNo
:
Number
(
dropColumnOrder
)
},
);
}
},
[]);
// 监听鼠标按下
const
onMouseDown
=
useCallback
(
(
e
)
=>
{
// 表格初始位置x点
const
originLeft
=
container
.
getBoundingClientRect
().
x
||
0
;
// 拖动列矩形
const
targetRect
=
e
.
currentTarget
.
getBoundingClientRect
();
const
curX
=
e
.
clientX
;
// 500ms长按事件,表示想要拖拽
timer
.
current
=
setTimeout
(()
=>
{
// 影子div显示
columnCopyDiv
.
style
.
display
=
'block'
;
// 影子div初始x位置=拖动列x点-表格x点
columnCopyDiv
.
style
.
left
=
`
${
targetRect
.
x
-
originLeft
}
px`
;
// 影子div宽度=拖动列宽度
columnCopyDiv
.
style
.
width
=
`
${
targetRect
.
width
}
px`
;
// 鼠标x点与拖动列x点之间的距离(记录下来方便后续使用)
const
detaX
=
curX
-
targetRect
.
x
;
columnCopyDiv
.
setAttribute
(
'data-deta-x'
,
String
(
detaX
));
// 分割线初始位置为当前列
divider
.
style
.
left
=
`
${
targetRect
.
x
-
originLeft
}
px`
;
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
],
);
return
(
return
(
<
div
<
div
className=
{
classNames
(
s
.
draggableDiv
,
className
)
}
className=
{
classNames
(
'draggableColumn'
,
className
)
}
style=
{
style
}
style=
{
style
}
draggable=
{
true
}
onMouseDown=
{
onMouseDown
}
onDragStart=
{
onDragStart
}
onMouseUp=
{
onMouseUp
}
onDrag=
{
onDragUpdate
}
data
-
column
-
name=
{
columnName
}
onDragEnd=
{
onDragEnd
}
data
-
column
-
order=
{
orderNo
}
onDragOver=
{
onDragOver
}
onDrop=
{
onDrop
}
>
>
{
props
.
children
}
{
props
.
children
}
</
div
>
</
div
>
...
...
components/apolloTable/component/Table.less
View file @
e9dc8a33
...
@@ -142,6 +142,7 @@
...
@@ -142,6 +142,7 @@
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;
\ No newline at end of file
}
components/apolloTable/component/Table.tsx
View file @
e9dc8a33
...
@@ -317,9 +317,10 @@ export default class AirTable extends Component<TableProps, TableState> {
...
@@ -317,9 +317,10 @@ export default class AirTable extends Component<TableProps, TableState> {
questionText
,
questionText
,
icon
,
icon
,
requiredFlag
,
requiredFlag
,
orderNo
,
}
=
showColumns
[
columnIndex
];
}
=
showColumns
[
columnIndex
];
return
(
return
(
<
DragSorted
column
Config=
{
showColumns
[
columnIndex
]
}
onDropFinish=
{
onDragSorted
}
onScroll=
{
this
.
onScrollHor
}
className=
{
styles
.
headerCell
}
key=
{
key
}
style=
{
style
}
>
<
DragSorted
column
Name=
{
columnName
}
orderNo=
{
orderNo
}
onDropFinish=
{
onDragSorted
}
onScroll=
{
this
.
onScrollHor
}
className=
{
styles
.
headerCell
}
key=
{
key
}
style=
{
style
}
>
<
ResizableBox
<
ResizableBox
width=
{
style
.
width
}
width=
{
style
.
width
}
handle=
{
handle=
{
...
@@ -805,7 +806,7 @@ export default class AirTable extends Component<TableProps, TableState> {
...
@@ -805,7 +806,7 @@ export default class AirTable extends Component<TableProps, TableState> {
}
}
}
}
/>
/>
</
div
>
</
div
>
<
div
id=
"columnCopyDiv"
className=
{
styles
.
columnCopyDiv
}
/>
<
div
id=
"columnCopyDiv"
className=
{
styles
.
columnCopyDiv
}
draggable=
{
true
}
/>
</
div
>
</
div
>
);
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment