我正在添加一个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>
其他回答
在其他一些回答中提到的“检查目标”方法的基础上,这里有一个更通用/实用的方法:
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])
);
在反复折腾之后,我发现这是最稳定的解决方案:
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>
在窗口上无条件地设置effectAllow和dropEffect会导致我的drop zone不再接受任何d-n-d,无论属性是否设置为新的。
jQuery的正确答案将是:
$(document).on({
dragover: function() {
return false;
},
drop: function() {
return false;
}
});
这里返回false将表现为event.preventDefault()和event.stopPropagation()。
为了只允许在某些元素上进行拖放,你可以这样做:
window.addEventListener("dragover",function(e){
e = e || event;
console.log(e);
if (e.target.tagName != "INPUT") { // check which element is our target
e.preventDefault();
}
},false);
window.addEventListener("drop",function(e){
e = e || event;
console.log(e);
if (e.target.tagName != "INPUT") { // check which element is our target
e.preventDefault();
}
},false);
下面是一个使用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>