내 페이지에 html5 드래그 앤 드롭 업 로더를 추가하고 있습니다.
파일을 업로드 영역에 놓으면 모든 것이 잘 작동합니다.
그러나 실수로 업로드 영역 외부에서 파일을 삭제하면 브라우저가 로컬 파일을 새 페이지 인 것처럼로드합니다.
이 동작을 어떻게 방지 할 수 있습니까?
감사!
답변
preventDefault()
모든 드래그 앤 드롭 이벤트 를 호출하는 이벤트 리스너를 창에 추가 할 수 있습니다 .
예:
window.addEventListener("dragover",function(e){
e = e || event;
e.preventDefault();
},false);
window.addEventListener("drop",function(e){
e = e || event;
e.preventDefault();
},false);
답변
많은 문제를 겪은 후 이것이 가장 안정적인 솔루션이라는 것을 알았습니다.
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
무조건 설정 하면 속성을 새로 설정했는지 여부에 관계없이 드롭 영역이 더 이상 dnd를 허용하지 않습니다.
답변
jQuery의 경우 정답은 다음과 같습니다.
$(document).on({
dragover: function() {
return false;
},
drop: function() {
return false;
}
});
다음 return 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);
답변
이 시도:
document.body.addEventListener('drop', function(e) {
e.preventDefault();
}, false);
답변
기본적으로 모든 끌어서 놓기 작업을 방지하는 것은 원하지 않을 수 있습니다. 적어도 일부 브라우저에서는 드래그 소스가 외부 파일인지 확인할 수 있습니다. 이 StackOverflow answer 에서 드래그 소스가 외부 파일인지 확인하는 기능을 포함 시켰습니다 .
Digital Plane의 답변을 수정하면 다음과 같이 할 수 있습니다.
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);
답변
참고 : 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 ()으로 인해 서로 간섭하지 않습니다.