我正在添加一个html5拖放上传程序到我的页面。
当文件被放入上传区域时,一切都很正常。
但是,如果我不小心将文件放到了上传区域之外,浏览器就会像加载新页面一样加载本地文件。
我该如何防止这种行为?
谢谢!
我正在添加一个html5拖放上传程序到我的页面。
当文件被放入上传区域时,一切都很正常。
但是,如果我不小心将文件放到了上传区域之外,浏览器就会像加载新页面一样加载本地文件。
我该如何防止这种行为?
谢谢!
当前回答
下面是一个使用ES6语法的更现代化的版本。
let dropzoneId = 'dropzone' const dragEventHandler = e => { if (e.target.id !== dropzoneId) { e.preventDefault e.dataTransfer.effectAllowed = 'none' e.dataTransfer.dropEffect = 'none' } } // window.addEventListener("dragenter", dragEventHandler, false) // window.addEventListener("dragover", dragEventHandler, false) // window.addEventListener("drop", dragEventHandler, false) ['dragenter', 'dragover', 'drop'].forEach(ev => window.addEventListener(ev, dragEventHandler, false)) <div id="dropzone">...</div>
其他回答
下面是一个使用ES6语法的更现代化的版本。
let dropzoneId = 'dropzone' const dragEventHandler = e => { if (e.target.id !== dropzoneId) { e.preventDefault e.dataTransfer.effectAllowed = 'none' e.dataTransfer.dropEffect = 'none' } } // window.addEventListener("dragenter", dragEventHandler, false) // window.addEventListener("dragover", dragEventHandler, false) // window.addEventListener("drop", dragEventHandler, false) ['dragenter', 'dragover', 'drop'].forEach(ev => window.addEventListener(ev, dragEventHandler, false)) <div id="dropzone">...</div>
您可以向窗口添加一个事件监听器,在所有拖放事件上调用preventDefault()。 例子:
window.addEventListener("dragover",function(e){
e = e || event;
e.preventDefault();
},false);
window.addEventListener("drop",function(e){
e = e || event;
e.preventDefault();
},false);
为了它的价值,我使用以下。如果不是特别优雅的话,可能会很好,很明确?
var myDropZone = document.getElementById('drop_zone');
// first, inhibit the default behaviour throughout the window
window.addEventListener('drop', () => {
event.preventDefault();
} );
window.addEventListener('dragover', () => {
event.dataTransfer.dropEffect = 'none'; // dont allow drops
event.preventDefault();
} );
// Next, allow the cursor to show 'copy' as it is dragged over
// my drop zone but dont forget to stop the event propagating
myDropZone.addEventListener('dragover', () => {
event.dataTransfer.dropEffect = 'copy';
event.stopPropagation(); // important !!
event.preventDefault();
} );
// In my drop zone, deal with files as they are dropped
myDropZone.addEventListener('drop', myDropHandler);
注意:尽管OP没有要求Angular的解决方案,但我来这里就是为了寻找它。所以我想分享一下我发现的一个可行的解决方案,如果你使用Angular的话。
根据我的经验,这个问题首先出现在向页面添加文件拖放功能时。因此,我的观点是,添加这个的组件,也应该负责防止删除区域之外的删除。
在我的解决方案中,拖放区域是一个带有类的输入,但任何明确的选择器都可以工作。
import { Component, HostListener } from '@angular/core';
//...
@Component({
template: `
<form>
<!-- ... -->
<input type="file" class="dropzone" />
</form>
`
})
export class MyComponentWithDropTarget {
//...
@HostListener('document:dragover', ['$event'])
@HostListener('drop', ['$event'])
onDragDropFileVerifyZone(event) {
if (event.target.matches('input.dropzone')) {
// In drop zone. I don't want listeners later in event-chain to meddle in here
event.stopPropagation();
} else {
// Outside of drop zone! Prevent default action, and do not show copy/move icon
event.preventDefault();
event.dataTransfer.effectAllowed = 'none';
event.dataTransfer.dropEffect = 'none';
}
}
}
当创建/销毁组件时,侦听器会自动添加/删除,并且由于stopPropagation(),在同一页面上使用相同策略的其他组件不会相互干扰。
试试这个:
document.body.addEventListener('drop', function(e) {
e.preventDefault();
}, false);