[英]How to attach drag event handlers to a React component using TypeScript
[英]How to Attach Drag & Drop Event Listeners to a React component
我正在构建一个组件,允许将本地文件拖放到 div 上。 然后是有关已删除文件的信息输出。
我的问题是我不知道如何在创建组件时正确附加事件侦听器drop
和dragover
。
我的 App 组件是我所有逻辑所在的地方(用于放置和拖动的处理程序),我创建了一个单独的组件,文件将放置在其中 - dropZone 组件。
我试图把事件侦听器的悬浮窗标签上我的应用程序组件与componentDidMount
那里,如果我的悬浮窗组件已经变得把一个事件监听器就可以了:
componentDidMount(){
const dropZone = document.getElementById('dropZone');
dropZone.addEventListener('dragover', this.allowDrop.bind(this))
dropZone.addEventListener('drop', this.dropHandler.bind(this))
}
这没有用
然后我尝试将它放在我的应用程序组件上的 dropZone 标签中:
<DropZone dropZone = {"dropZone"} onDragOver = {this.allowDrop.bind(this)}
onDrop ={this.dropHandler.bind(this)} >
</DropZone>
这也没有向 dropZone 添加事件侦听器。 我已经尝试了其他一些事情,但这些是我认为应该工作的事情。
所以我的问题是,
如何将drop
和dragover
事件侦听器添加到 dropZone?
我应该在 App 上添加这些事件侦听器并将它们作为道具传递给 dropZone 组件吗? 或者甚至不需要传递
或者我应该直接在 dropZone 上添加事件侦听器,以便我的事件处理程序函数存在于 dropZone 组件中?
你不需要使用道具。 您可以在 DropZone 组件中添加所有事件。
http://codepen.io/jzmmm/pen/bZjzxN?editors=0011
这是我添加事件的地方:
componentDidMount() {
window.addEventListener('mouseup', this._onDragLeave);
window.addEventListener('dragenter', this._onDragEnter);
window.addEventListener('dragover', this._onDragOver);
window.addEventListener('drop', this._onDrop);
document.getElementById('dragbox').addEventListener('dragleave', this._onDragLeave);
}
你的渲染方法:
render() {
return (
<div>
{this.props.children}
<div id="dragbox" className={this.state.className}>
Drop a file to Upload
</div>
</div>
);
}
正如您在 componentDidMount 中看到的,我也向 #dragbox 添加了一个事件侦听器。 因为一旦您将文件拖到页面上,#dragbox 就会位于鼠标光标下方,所以它需要一个 dragleave,以防您决定不想将文件放在那里。
此外,需要dragover
来捕获drop
然后在我的 App 组件中,我可以这样使用它:
class App extends React.Component {
render() {
return (
<DropZone>
<div>
<h1>Drag A File Here...</h1>
</div>
</DropZone>
);
}
}
使用样式组件库和 React Hooks 的@mnsr 答案版本
const DragBox = styled.div(({ isVisible }: { isVisible }) =>
isVisible
? `
position: fixed;
display: flex;
border: 15px dashed white;
width: 100%;
height: 100%;
z-index: 2000;
top: 0;
left: 0;
right: 0;
bottom: 0;
flex: 1;
justify-content: center;
align-items: center;
text-align: center;
font-size: 30px;
font-weight: 600;
color: white;
letter-spacing: 1px;
margin: auto;
`
: 'display: none;'
);
const DropZone = ({ children }) => {
const [isVisible, setIsVisible] = useState(false);
const onDragEnter = useCallback((e) => {
setIsVisible(true);
e.stopPropagation();
e.preventDefault();
return false;
}, []);
const onDragOver = useCallback((e) => {
e.preventDefault();
e.stopPropagation();
return false;
}, []);
const onDragLeave = useCallback((e) => {
setIsVisible(false);
e.stopPropagation();
e.preventDefault();
return false;
}, []);
const onDrop = useCallback((e) => {
e.preventDefault();
const files = e.dataTransfer.files;
console.log('Files dropped: ', files);
// Upload files
setIsVisible(false);
return false;
}, []);
useEffect(() => {
window.addEventListener('mouseup', onDragLeave);
window.addEventListener('dragenter', onDragEnter);
window.addEventListener('dragover', onDragOver);
window.addEventListener('drop', onDrop);
return () => {
window.removeEventListener('mouseup', onDragLeave);
window.removeEventListener('dragenter', onDragEnter);
window.removeEventListener('dragover', onDragOver);
window.removeEventListener('drop', onDrop);
};
}, [onDragEnter, onDragLeave, onDragOver, onDrop]);
return (
<div>
{children}
<DragBox
className="bg-secondary"
isVisible={isVisible}
onDragLeave={onDragLeave}
>
Drop files to Upload
</DragBox>
</div>
);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.