防止浏览器加载拖放文件

我正在添加一个html5的拖放上传到我的网页。

当一个文件被放入上传区域时,一切正常。

但是,如果我不小心将文件放在上载区域之外,浏览器将加载本地文件,就好像它是新页面一样。

我怎样才能防止这种行为?

谢谢!

您可以将事件侦听器添加到调用所有dragover和drop事件的preventDefault()的窗口中。
例:

 window.addEventListener("dragover",function(e){ e = e || event; e.preventDefault(); },false); window.addEventListener("drop",function(e){ e = e || event; e.preventDefault(); },false); 

经过大量的摆弄之后,我发现这是最稳定的解决scheme:

 var dropzoneId = "dropzone"; window.addEventListener("dragenter", function(e) { if (e.target.id != dropzoneId) { e.preventDefault(); e.dataTransfer.effectAllowed = "none"; e.dataTransfer.dropEffect = "none"; } }, false); window.addEventListener("dragover", function(e) { if (e.target.id != dropzoneId) { e.preventDefault(); e.dataTransfer.effectAllowed = "none"; e.dataTransfer.dropEffect = "none"; } }); window.addEventListener("drop", function(e) { if (e.target.id != dropzoneId) { e.preventDefault(); e.dataTransfer.effectAllowed = "none"; e.dataTransfer.dropEffect = "none"; } }); 
 <div id="dropzone">...</div> 

为了只允许拖放一些元素,你可以做一些事情:

 window.addEventListener("dragover",function(e){ e = e || event; console.log(e); if (e.target.tagName != "INPUT") { // check wich element is our target e.preventDefault(); } },false); window.addEventListener("drop",function(e){ e = e || event; console.log(e); if (e.target.tagName != "INPUT") { // check wich element is our target e.preventDefault(); } },false); 

对于jQuery,正确的答案是:

 $(document).on({ dragover: function() { return false; }, drop: function() { return false; } }); 

这里return false将performance为event.preventDefault()event.stopPropagation()

默认情况下阻止所有拖放操作可能不是您想要的。 至less在某些浏览器中,可以检查拖动源是否是外部文件。 我已经包含了一个函数来检查拖动源是否是这个StackOverflow答案中的外部文件。

修改数字平面的答案,你可以做这样的事情:

 function isDragSourceExternalFile() { // Defined here: // https://stackoverflow.com/a/32044172/395461 } window.addEventListener("dragover",function(e){ e = e || event; var IsFile = isDragSourceExternalFile(e.originalEvent.dataTransfer); if (IsFile) e.preventDefault(); },false); window.addEventListener("drop",function(e){ e = e || event; var IsFile = isDragSourceExternalFile(e.originalEvent.dataTransfer); if (IsFile) e.preventDefault(); },false); 

尝试这个:

 document.body.addEventListener('drop', function(e) { e.preventDefault(); }, false); 

build立在其他一些答案中概述的“检查目标”方法,这里是一个更通用/function的方法:

 function preventDefaultExcept(predicates) { return function (e) { var passEvery = predicates.every(function (predicate) { return predicate(e); }) if (!passEvery) { e.preventDefault(); } }; } 

被调用如:

 function isDropzone(e) { return e.target.id === 'dropzone'; } function isntParagraph(e) { return e.target.tagName !== 'p'; } window.addEventListener( 'dragover', preventDefaultExcept([isDropzone, isntParagraph]) ); window.addEventListener( 'drop', preventDefaultExcept([isDropzone]) ); 

我有一个HTML objectembed ),填充页面的宽度和高度。 @数字平面的答案在普通的网页上工作,但如果用户掉到一个embedded的对象上,则不会。 所以我需要一个不同的解决scheme

如果我们切换到使用事件捕获阶段,我们可以在embedded对象接收它们之前获取事件(注意在事件侦听器调用结束时的true值):

 // document.body or window document.body.addEventListener("dragover", function(e){ e = e || event; e.preventDefault(); console.log("over true"); }, true); document.body.addEventListener("drop", function(e){ e = e || event; e.preventDefault(); console.log("drop true"); }, true); 

使用下面的代码(基于@ digital-plane的答案)页面变成一个拖动目标,它可以防止对象embedded捕获事件,然后加载我们的图像:

 document.body.addEventListener("dragover", function(e){ e = e || event; e.preventDefault(); console.log("over true"); }, true); document.body.addEventListener("drop",function(e){ e = e || event; e.preventDefault(); console.log("Drop true"); // begin loading image data to pass to our embed var droppedFiles = e.dataTransfer.files; var fileReaders = {}; var files = {}; var reader; for (var i = 0; i < droppedFiles.length; i++) { files[i] = droppedFiles[i]; // bc file is ref is overwritten console.log("File: " + files[i].name + " " + files[i].size); reader = new FileReader(); reader.file = files[i]; // bc loadend event has no file ref reader.addEventListener("loadend", function (ev, loadedFile) { var fileObject = {}; var currentReader = ev.target; loadedFile = currentReader.file; console.log("File loaded:" + loadedFile.name); fileObject.dataURI = currentReader.result; fileObject.name = loadedFile.name; fileObject.type = loadedFile.type; // call function on embed and pass file object }); reader.readAsDataURL(files[i]); } }, true); 

在Mac上testingFirefox。