#html #file #file-io #drag-and-drop
#HTML #файл #file-io #перетаскивание
Вопрос:
У меня есть HTML-форма, которая содержит поле ввода файла с возможностью выбора нескольких файлов, и у меня также есть функция перетаскивания, над которой я также работаю. Мой вопрос в том, как легко интегрировать обе эти функции, если это вообще возможно?
В идеале я хотел бы, чтобы пользователь выбирал свои файлы либо с помощью drag’n’drop, либо через диалоговое окно file. Как только пользователь закончит выбирать свои файлы, нажмите кнопку отправки формы для загрузки.
Я предполагаю, что основная неопределенность, которая у меня есть, заключается в том, как привязать файлы, которые были перетащены, к полю ввода файла для отправки формы.
Комментарии:
1. Где вы можете заставить это работать?
Ответ №1:
Я написал некоторый код jQuery, который делает именно это, скажите мне, работает ли это у вас.
<!DOCTYPE html>
<html>
<head>
<title>Multiple DnD Uploader</title>
<link rel="stylesheet" href="style.css" />
<script type = "text/javascript" src = "../music/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#drop').change(function(event){
files = event.target.files;
$('#drop').css('display', 'none');
for(var i = 0, len = files.length; i < len; i ) {
if((files[i].fileName "").substring((files[i].fileName "").length-4,(files[i].fileName "").length)=='.mp3'){
$.ajax({
type: "POST",
url: "uploader.php?id=" i,
contentType: "multipart/form-data",
headers: {
"X-File-Name" : files[i].fileName,
"X-File-Size" : files[i].fileSize,
"X-File-Type" : files[i].type
},
beforeSend: function() {
$('#info').append('<li class="indicator"><span class="label">File Name :</span> ' files[i].fileName ' | <span class="label">Size :</span> ' files[i].fileSize ' | <img id="' i '" src="loading.gif" /></li>');
},
processData: false,
data: files[i],
success: function(data){
$('#' data).attr('src', 'check.png');
},error: function(data){
$('#info').append('Error: ' data '<br />');
}
});
}else{
$('#info').append('Error: Incorrect file type. Looking for .mp3');
}
}
});
});
</script>
</head>
<body>
<div id="drop">
<h1>Drop files here</h1>
<p>To add them as attachments</p>
<input type="file" multiple="true" id="filesUpload" />
</div>
<div id="info">
</div>
</body>
</html>
И PHP-файл выглядит следующим образом:
<?php
$headers = array();
foreach ($_SERVER as $k => $v){
if(substr($k, 0, 5) == "HTTP_"){
$k = str_replace('_', ' ', substr($k, 5));
$k = str_replace(' ', '-', ucwords(strtolower($k)));
$headers[$k] = $v;
}
}
$file = new stdClass;
$file->name = basename($headers['X-File-Name']);
$file->size = $headers['X-File-Size'];
$file->content = file_get_contents("php://input");
if(file_put_contents('files/'.$file->name, $file->content))
echo $_GET['id'];
?>
Комментарии:
1. Если я перетаскиваю файл в зону удаления, я хотел бы взять эти данные и добавить их в поле ввода файла, которое пользователь обычно нажимает, чтобы открыть диалоговое окно файла. Неясно, как это сделать или есть ли какие-либо проблемы с безопасностью. Кроме того, если я правильно понимаю, file input multiple действует как массив, так что при отправке формы будет отправлен массив данных, связанных с файлом.
2. Что ж, что вы можете сделать, это просто изменить успешный вызов jquery на что-то вроде этого:
$('#files').append(files[data].fileName);
Если я вас не неправильно понял.
Ответ №2:
Я не совсем уверен, как вы это делаете, поэтому я расскажу вам, как я это делаю, а затем попытаюсь ответить на ваш вопрос.
- Настройте прослушиватели событий для удаления и изменения события <input>.
- для удаления:
filesUpload.addEventListener("change", function () {traverseFiles(this.files);}, false);
- для <ввода>:
dropArea.addEventListener("drop", function (evt) {traverseFiles(evt.dataTransfer.files);}, false);
- для удаления:
traverseFiles
то, что вы видите выше, — это функция, которая получаетFileList
(массивFile
файлов), которые являются частью File API. Затем эта функция вызывает функциюuploadFile
для каждогоFile
.uploadFile
отправляетFile
асинхронно через ajax (XMLHttpRequest.send(file)
).
Теперь, чтобы ответить на ваш вопрос, как привязать удаленные файлы к полю ввода: вы этого не делаете, вы просто делаете это другим способом. Вы создаете API или оболочку для загрузки файлов, а затем, если пользователь удаляет файлы, вы вызываете эту функцию-оболочку. Если пользователь нажимает на поле <ввод>, вы снова вызываете эту оболочку (как я сделал с traverseFiles).
Имеет смысл? Если этого не произойдет, скажите мне, какая часть, и я отредактирую этот ответ / расширю его.
Ответ №3:
<input type=file multiple>
<div id='dropzone'>Drop Files Here</div>
события onchange и ondrop должны связать функцию с переменной, чтобы получить список файлов.
var files=e.target.files||e.dataTransfer.files
Ответ №4:
Вы могли бы использовать «HTML5-File-Uploader», который предназначен для выполнения того, что вам нужно, а также для корректного изменения для старых браузеров:
https://github.com/gre/HTML5-File-Uploader/wiki
Я сам этого не пробовал.
В качестве альтернативы, вы могли бы взглянуть на эту страницу, которая предоставляет весь код, необходимый для выполнения этого самостоятельно: