[html] 드롭 파일을 표준 html 파일 입력으로 드래그

요즘에는 파일을 특수 컨테이너에 끌어다 놓고 XHR 2로 업로드 할 수 있습니다. 라이브 진행률 표시 줄 등. 매우 멋진 기능. 여기 예입니다.

그러나 때때로 우리는 그처럼 시원함을 원하지 않습니다. 내가 원하는 것은 드래그 앤 드롭 파일입니다 – 한 번에 많은 – 표준 HTML 파일 입력에 : <input type=file multiple>.

가능합니까? 파일 드롭에서 올바른 파일 이름 (?)으로 파일 입력을 ‘채우는’방법이 있습니까? 파일 시스템 보안상의 이유로 전체 파일 경로를 사용할 수 없습니다.

왜? 일반 양식을 제출하고 싶습니다. 모든 브라우저 및 모든 장치에 적용됩니다. 드래그 앤 드롭은 UX를 향상 및 단순화하기 위해 점진적으로 향상되었습니다. 표준 파일 입력 (+ multiple속성)이있는 표준 양식 이 있습니다. HTML5 향상 기능을 추가하고 싶습니다.

편집
내가 알고있는 몇 가지 브라우저 작업을 수행 할 수 있습니다 가끔 (거의 항상) 파일 입력 자체에 파일을 놓습니다. Chrome은 일반적 으로이 작업을 수행하지만 때로는 실패하고 현재 페이지에 파일을로드합니다 (양식을 작성하면 큰 실패). 나는 바보와 브라우저 증거를하고 싶다.



답변

다음은 Chrome 및 FF에서 작동하지만 IE10 이상을 다루는 솔루션을 아직 찾지 못했습니다.

// dragover and dragenter events need to have 'preventDefault' called
// in order for the 'drop' event to register. 
// See: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations#droptargets
dropContainer.ondragover = dropContainer.ondragenter = function(evt) {
  evt.preventDefault();
};

dropContainer.ondrop = function(evt) {
  // pretty simple -- but not for IE :(
  fileInput.files = evt.dataTransfer.files;

  // If you want to use some of the dropped files
  const dT = new DataTransfer();
  dT.items.add(evt.dataTransfer.files[0]);
  dT.items.add(evt.dataTransfer.files[3]);
  fileInput.files = dT.files;

  evt.preventDefault();
};
<!DOCTYPE html>
<html>
<body>
<div id="dropContainer" style="border:1px solid black;height:100px;">
   Drop Here
</div>
  Should update here:
  <input type="file" id="fileInput" />
</body>
</html>

addEventListenerevt 핸들러를 등록 하기 위해 또는 jQuery 등 을 사용하고 싶을 것입니다 .


답변

나는 이것에 대한 해결책을 만들었다.

이 방법의 드래그 앤 드롭 기능은 Chrome, Firefox 및 Safari에서만 작동합니다. (IE10과 호환되는지는 모르겠지만) 다른 브라우저의 경우 “또는 여기를 클릭하십시오”단추가 제대로 작동합니다.

입력 필드는 파일을 특정 영역 위로 드래그 할 때 마우스를 따라 가며 버튼도 추가했습니다.

주석 해제 불투명도 : 0; 파일 입력 만 표시되므로 진행 상황을 확인할 수 있습니다.


답변

이것이 “DTHML”HTML5 방식입니다. 일반 양식 입력 (Ricardo Tomasi가 지적한 대로만 읽음). 그런 다음 파일을 끌어다 놓으면 양식에 첨부됩니다. 이 방법으로 업로드 된 파일을 승인하려면 작업 페이지를 수정해야합니다.

function readfiles(files) {
  for (var i = 0; i < files.length; i++) {
    document.getElementById('fileDragName').value = files[i].name
    document.getElementById('fileDragSize').value = files[i].size
    document.getElementById('fileDragType').value = files[i].type
    reader = new FileReader();
    reader.onload = function(event) {
      document.getElementById('fileDragData').value = event.target.result;}
    reader.readAsDataURL(files[i]);
  }
}
var holder = document.getElementById('holder');
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
  this.className = '';
  e.preventDefault();
  readfiles(e.dataTransfer.files);
}
#holder.hover { border: 10px dashed #0c0 !important; }
<form method="post" action="http://example.com/">
  <input type="file"><input id="fileDragName"><input id="fileDragSize"><input id="fileDragType"><input id="fileDragData">
  <div id="holder" style="width:200px; height:200px; border: 10px dashed #ccc"></div>
</form>

전체 창을 놓기 영역으로 만들 수 있다면 더 보스입니다. Gmail처럼 창에 들어오고 나가는 HTML5 드래그 이벤트를 어떻게 감지합니까?를 참조하십시오.


답변

//----------App.js---------------------//
$(document).ready(function() {
    var holder = document.getElementById('holder');
    holder.ondragover = function () { this.className = 'hover'; return false; };
    holder.ondrop = function (e) {
      this.className = 'hidden';
      e.preventDefault();
      var file = e.dataTransfer.files[0];
      var reader = new FileReader();
      reader.onload = function (event) {
          document.getElementById('image_droped').className='visible'
          $('#image_droped').attr('src', event.target.result);
      }
      reader.readAsDataURL(file);
    };
});
.holder_default {
    width:500px;
    height:150px;
    border: 3px dashed #ccc;
}

#holder.hover {
    width:400px;
    height:150px;
    border: 3px dashed #0c0 !important;
}

.hidden {
    visibility: hidden;
}

.visible {
    visibility: visible;
}
<!DOCTYPE html>

<html>
    <head>
        <title> HTML 5 </title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js"></script>
    </head>
    <body>
      <form method="post" action="http://example.com/">
        <div id="holder" style="" id="holder" class="holder_default">
          <img src="" id="image_droped" width="200" style="border: 3px dashed #7A97FC;" class=" hidden"/>
        </div>
      </form>
    </body>
</html>


답변

이론적으로을 오버레이하는 요소를 추가 한 <input/>다음 해당 drop이벤트를 사용하여 파일을 캡처하고 (File API 사용) 입력 files배열에 전달할 수 있습니다 .

파일 입력이 읽기 전용 인 것을 제외하고 . 이것은 오래된 문제입니다.

그러나 양식 컨트롤을 완전히 무시하고 XHR을 통해 업로드 할 수 있습니다 (지원 여부는 확실하지 않음).

주변 영역의 요소를 사용하여 Chrome에서 드롭 이벤트를 취소하고 파일을로드하는 기본 동작을 방지 할 수도 있습니다.

입력 위에 여러 파일을 삭제하면 Safari 및 Firefox에서 이미 작동합니다.


답변

이것이 내가 나온 것입니다.

Jquery와 HTML 사용 삽입 파일에 추가됩니다.

var dropzone = $('#dropzone')


dropzone.on('drag dragstart dragend dragover dragenter dragleave drop', function(e) {
    e.preventDefault();
    e.stopPropagation();
  })

dropzone.on('dragover dragenter', function() {
    $(this).addClass('is-dragover');
  })
dropzone.on('dragleave dragend drop', function() {
    $(this).removeClass('is-dragover');
  })

dropzone.on('drop',function(e) {
	var files = e.originalEvent.dataTransfer.files;
	// Now select your file upload field 
	// $('input_field_file').prop('files',files)
  });
input {	margin: 15px 10px !important;}

.dropzone {
	padding: 50px;
	border: 2px dashed #060;
}

.dropzone.is-dragover {
  background-color: #e6ecef;
}

.dragover {
	bg-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="" draggable='true' style='padding: 20px'>
	<div id='dropzone' class='dropzone'>
		Drop Your File Here
	</div>
	</div>


답변

CSS 전용 솔루션의 경우 :

<div class="file-area">
    <input type="file">
    <div class="file-dummy">
        <span class="default">Click to select a file, or drag it here</span>
        <span class="success">Great, your file is selected</span>
    </div>
</div>

.file-area {
    width: 100%;
    position: relative;
    font-size: 18px;
}
.file-area input[type=file] {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    opacity: 0;
    cursor: pointer;
}
.file-area .file-dummy {
    width: 100%;
    padding: 50px 30px;
    border: 2px dashed #ccc;
    background-color: #fff;
    text-align: center;
    transition: background 0.3s ease-in-out;
}
.file-area .file-dummy .success {
    display: none;
}
.file-area:hover .file-dummy {
    border: 2px dashed #1abc9c;
}
.file-area input[type=file]:valid + .file-dummy {
    border-color: #1abc9c;
}
.file-area input[type=file]:valid + .file-dummy .success {
    display: inline-block;
}
.file-area input[type=file]:valid + .file-dummy .default {
    display: none;
}

https://codepen.io/Scribblerockerz/pen/qdWzJw 에서 수정