Commit b7bcf014 by zhaochengxiang

模型字段拖动自动滚动

parent 49e332c5
/*------------------------------------------------*/
/* LIBRARIES
/*------------------------------------------------*/
import throttle from "lodash/throttle";
/*------------------------------------------------*/
/* CONSTANTS
/*------------------------------------------------*/
const OFFSET = 1; // This is the top/bottom offset you use to start scrolling in the div.
const PX_DIFF = 1;
/*------------------------------------------------*/
/* GLOBAL VARIABLES
/*------------------------------------------------*/
let scrollIncrement = 0;
let isScrolling = false;
let sidebarElement = null;
let scrollHeightSidebar = 0;
let clientRectBottom = 0;
let clientRectTop = 0;
/*------------------------------------------------*/
/* METHODS
/*------------------------------------------------*/
/**
* Scroll up in the sidebar.
*/
const goUp = () => {
scrollIncrement -= PX_DIFF;
sidebarElement.scrollTop = scrollIncrement;
if (isScrolling && scrollIncrement >= 0) {
window.requestAnimationFrame(goUp);
}
};
/**
* Scroll down in the sidebar.
*/
const goDown = () => {
scrollIncrement += PX_DIFF;
sidebarElement.scrollTop = scrollIncrement;
if (isScrolling && scrollIncrement <= scrollHeightSidebar) {
window.requestAnimationFrame(goDown);
}
};
const onDragOver = (event) => {
const isMouseOnTop =
scrollIncrement >= 0 &&
event.clientY > clientRectTop &&
event.clientY < clientRectTop + OFFSET;
const isMouseOnBottom =
scrollIncrement <= scrollHeightSidebar &&
event.clientY > clientRectBottom - OFFSET &&
event.clientY <= clientRectBottom;
if (!isScrolling && (isMouseOnTop || isMouseOnBottom)) {
isScrolling = true;
scrollIncrement = sidebarElement.scrollTop;
if (isMouseOnTop) {
window.requestAnimationFrame(goUp);
} else {
window.requestAnimationFrame(goDown);
}
} else if (!isMouseOnTop && !isMouseOnBottom) {
isScrolling = false;
}
};
/**
* The "throttle" method prevents executing the same function SO MANY times.
*/
const throttleOnDragOver = throttle(onDragOver, 150);
const addEventListenerForSidebar = (elementId) => {
// In Chrome the scrolling works.
if (navigator.userAgent.indexOf("Chrome") === -1) {
sidebarElement = document.getElementById(elementId);
scrollHeightSidebar = sidebarElement.scrollHeight;
const clientRect = sidebarElement.getBoundingClientRect();
clientRectTop = clientRect.top;
clientRectBottom = clientRect.bottom;
sidebarElement.addEventListener("dragover", throttleOnDragOver);
}
};
const removeEventListenerForSidebar = () => {
isScrolling = false;
if (sidebarElement) {
sidebarElement.removeEventListener("dragover", throttleOnDragOver);
}
};
/*------------------------------------------------*/
/* EXPORTS
/*------------------------------------------------*/
export default {
addEventListenerForSidebar,
removeEventListenerForSidebar
};
......@@ -5,6 +5,7 @@ import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper';
import Helper from './Help';
import './ImportActionIndex.less';
import { showMessage, highlightSearchContentByTerms } from '../../../../util';
......@@ -239,7 +240,13 @@ const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) =>
const [, drag] = useDrag(
() => ({
type,
item: { index },
item: () => {
Helper.addEventListenerForSidebar("containerId");
return { index };
},
end: (_, __) => {
Helper.removeEventListenerForSidebar();
},
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
......@@ -603,18 +610,36 @@ const ImportActionIndex = (props) => {
return hasValidateReports ? includeValidateColumn : columns;
}
//解决拖动自动滚动问题
//https://codesandbox.io/s/react-dnd-example-12-s3nnf
let pendingUpdateFn = undefined;
let requestedFrame = undefined;
const drawFrame = () => {
const newData = update(data, pendingUpdateFn);
onChange && onChange(newData);
pendingUpdateFn = undefined;
requestedFrame = undefined;
};
const scheduleUpdate = (updateFn) => {
pendingUpdateFn = updateFn;
if (!requestedFrame) {
requestedFrame = requestAnimationFrame(drawFrame);
}
}
const moveRow = useCallback(
(dragIndex, hoverIndex) => {
const dragRow = data[dragIndex];
const newData = update(data, {
scheduleUpdate({
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragRow],
],
});
onChange && onChange(newData);
},
//eslint-disable-next-line react-hooks/exhaustive-deps
[data],
......@@ -653,7 +678,7 @@ const ImportActionIndex = (props) => {
editable && <Button className='ml-3' type="primary" onClick={onAddClick} disabled={ editingKey!==null || keyword!=='' } >新增索引</Button>
}
</div>
<div className='content'>
<div id="containerId">
<DndProvider backend={HTML5Backend} >
<Form form={form} component={false} onValuesChange={onValuesChange}>
<Table
......
.model-import-action-index {
.content {
.yy-table {
max-height: 200px !important;
overflow: auto !important;
}
......
......@@ -7,7 +7,7 @@ import update from 'immutability-helper';
import { generateUUID, highlightSearchContentByTerms, showMessage } from '../../../../util';
import { dispatchLatest } from '../../../../model';
import Helper from './Help';
import './ImportActionTable.less';
const { Option } = Select;
......@@ -202,7 +202,13 @@ const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) =>
const [, drag] = useDrag(
() => ({
type,
item: { index },
item: () => {
Helper.addEventListenerForSidebar("containerId");
return { index };
},
end: (_, __) => {
Helper.removeEventListenerForSidebar();
},
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
......@@ -694,18 +700,36 @@ const ImportActionTable = (props) => {
return hasValidateReports ? includeValidateColumn : columns;
}
//解决拖动自动滚动问题
//https://codesandbox.io/s/react-dnd-example-12-s3nnf
let pendingUpdateFn = undefined;
let requestedFrame = undefined;
const drawFrame = () => {
const newData = update(data, pendingUpdateFn);
onChangeRef.current && onChangeRef.current(newData);
pendingUpdateFn = undefined;
requestedFrame = undefined;
};
const scheduleUpdate = (updateFn) => {
pendingUpdateFn = updateFn;
if (!requestedFrame) {
requestedFrame = requestAnimationFrame(drawFrame);
}
}
const moveRow = useCallback(
(dragIndex, hoverIndex) => {
const dragRow = data[dragIndex];
const newData = update(data, {
scheduleUpdate({
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragRow],
],
});
onChangeRef.current && onChangeRef.current(newData);
},
//eslint-disable-next-line react-hooks/exhaustive-deps
[data],
......@@ -744,7 +768,7 @@ const ImportActionTable = (props) => {
editable && <Button className='ml-3' type="primary" onClick={onAddClick} disabled={ editingKey!=='' || keyword!=='' } >新增字段</Button>
}
</div>
<div className='content'>
<div id="containerId">
<DndProvider backend={HTML5Backend} >
<Form form={form} component={false} onValuesChange={onValuesChange}>
<Table
......
.model-import-action-table {
.content {
.yy-table {
max-height: 400px !important;
overflow: auto !important;
}
......
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