我正在创建自己的拖放区,并且想在拖动特定文件扩展名时执行操作,我发现onDragEnter
无法访问文件类型,onDrop
仅能做到这一点。
但是我找到了一个可以做我想做的东西的库,我试图从源代码中知道他们是怎么做的,但是我失败了。这是代码的链接
https://react-dropzone.netlify.com/#!/Accepting%20specific%20file%20types/5
答案 0 :(得分:0)
实际上文件类型可用,我不知道dropzone是如何反应的,但是您可以通过DragEvent.dataTransfer.items[0].type
访问该类型,items
是要拖动的项目数组,因此您可以访问其他人则通过items[1]
等
$('div').on('dragover',function(e){
console.log(e.originalEvent.dataTransfer.items[0].type);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>dropzone</div>
答案 1 :(得分:0)
好吧,onDragEnter
没有为您提供此信息,但是您可以从onDragOver
获得该信息。
要使用React做到这一点,我想最简单的方法是使用ref回调将元素放入您要放置的位置(或直接使用该元素上的事件)。
setTargetDropZone( element ) {
if (this.dropZone) {
// remove any previous attached event
this.dropZone.removeEventListener('dragover', this.onDragOver );
}
// update the local field with the new element
this.dropZone = element;
if (!this.dropZone) {
return;
}
// if it is not null attach the new event
this.dropZone.addEventListener( 'dragover', this.onDragOver );
}
在某些地方,您必须定义要接受的文件类型,然后必须处理传入的数据以对其进行过滤。
const { fileTypes = null } = this.props;
const { items } = e.dataTransfer;
let dropCount = items.length;
// if it is restricted, count how many actually match
if (fileTypes) {
// items is not an array, so you could use Array.from here
dropCount = Array.from( items ).filter( item => fileTypes.some( type => item.type.includes( type ) ) ).length;
}
因此,如果您结合使用此代码,最终可能会得到类似这样的结果
const { Component } = React;
const DropState = {
'All': '0',
'No': '1',
'Some': '2',
'0': 'All',
'1': 'No',
'2': 'Some'
};
class DropZone extends Component {
constructor() {
super();
this.state = {
dropState: DropState.All,
dropCount: 0
};
this.setTargetDropZone = this.setTargetDropZone.bind( this );
}
onDragOver = e => {
const { fileTypes = null } = this.props;
const { items } = e.dataTransfer;
let dropCount = items.length;
if (fileTypes) {
dropCount = Array.from( items ).filter( item => fileTypes.some( type => item.type.includes( type ) ) ).length;
}
this.setState( {
dropCount,
dropState: dropCount === items.length ? DropState.All : dropCount === 0 ? DropState.No : DropState.Some
} );
}
setTargetDropZone( element ) {
if (this.dropZone) {
this.dropZone.removeEventListener('dragover', this.onDragOver );
}
this.dropZone = element;
if (!this.dropZone) {
return;
}
this.dropZone.addEventListener( 'dragover', this.onDragOver );
}
render() {
const { dropState, dropCount } = this.state;
const { placeholder = 'Drop some files here' } = this.props;
return (
<div ref={this.setTargetDropZone} style={{border: 'solid #a0a0a0 1px' }}>
{ dropCount > 0 && <span>{ `${DropState[dropState]} will be accepted (${dropCount})` }</span> }
{ dropCount === 0 && placeholder }
</div>
);
}
}
const container = document.querySelector('#container');
ReactDOM.render( <DropZone fileTypes={ ['image/jpg', 'image/jpeg', 'image/png' ] } />, container );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container">
</div>