JavaScript と PHP でドラッグドロップでファイルをアップロードする

ファイルの進行状況を表示するプログレスバーを追加しました。

DEMO

ファイルをここにドロップ

または

※デモでは実際にアップロードはされません。

HTML

<p id="response"></p>
<div id="dropto">ファイルをここにドロップ</div>
<div id="progress"><div id="percent"></div></div>
または<input name="userfile" type="file" id="input-file">

CSS

#dropto {
background: #FFC;
border: 2px dashed #CCC;
height: 200px;
line-height:200px;
text-align: center;
color: #CCC;
}
#dropto.over { background: lightgreen; }
#progress { width: 100%; }
#percent { background: #55d49b; margin: 20px 0; width: 0; height: 10px; }

JavaScript

var dropFileUpload = function(arg) {
this.dropElm = document.querySelector(arg.dropElm);
this.progress = document.querySelector(arg.progress);
this.response = document.querySelector(arg.response);
this.inputFile = document.querySelector(arg.inputFile);
};
dropFileUpload.prototype = {
init: function() {
var self = this;
this.dropElm.addEventListener('drop', function(e) {
self.drop.call(self, e);
}, false);
this.dropElm.addEventListener('dragover', function(e) {
self.dragOver.call(self, e);
}, false);
this.inputFile.addEventListener('change', function(e) {
self.handleFiles.call(self, e);
}, false);
},
dragOver: function(e) {
e.preventDefault();
this.dropElm.setAttribute('class', 'over');
},
drop: function(e) {
e.preventDefault();
this.dropElm.setAttribute('class', '');
var readerFile = e.dataTransfer.files[0];
var file = e.dataTransfer.files;
this.handleFileSelect.call(this, readerFile, file);
},
handleFiles: function(e) {
var readerFile = e.target.files[0];
var file = e.target.files;
this.handleFileSelect.call(this, readerFile, file);
},
handleFileSelect: function(readerFile, file) {
var self = this;
if(!file && !readerFile)
return;
self.progress.style.width = '0%';
self.progress.textContent = '0%';
var reader = new FileReader();
reader.addEventListener('error', function(e) {
self.fileErrorHandler.call(self, e);
}, false);
reader.addEventListener('progress', function(e) {
self.updateProgress.call(self, e);
}, false);
reader.onabort = function(e) {
self.response.innerHTML = 'File read cancelled';
};
reader.onload = (function(e) {
self.upload.call(self, file);
});
reader.readAsBinaryString(readerFile);
},
updateProgress: function(e) {
if (e.lengthComputable) {//全体のサイズがわかっているかどうか
var percentLoaded = Math.round((e.loaded / e.total) * 100);
//if (percentLoaded < 100) {
this.progress.style.width = percentLoaded + '%';
this.progress.textContent = percentLoaded + '%';
//}
}
},
fileErrorHandler: function(e) {
switch(e.target.error.code) {
case e.target.error.NOT_FOUND_ERR:
this.response.innerHTML = 'File Not Found!';
break;
case e.target.error.NOT_READABLE_ERR:
this.response.innerHTML = 'File is not readable';
break;
case e.target.error.ABORT_ERR:
break;
default:
this.response.innerHTML = 'An error occurred reading this file.';
};
},
upload: function (files) {
var self = this;
var f = new FormData();
f.append('userfile', files[0]);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'up.php');
xhr.send(f);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200){
self.response.innerHTML = xhr.responseText;
}
};
}
};
var df = new dropFileUpload({
dropElm: '#dropto',
progress: '#percent',
response: '#response',
inputFile: '#input-file'
});
df.init();

PHP

$uploaddir = 'uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "アップロードに成功しました";
} else {
echo "アップロードに失敗しました";
}

参考文献

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください