インターネットサイトを作った時に、データをアップロードする仕様にしたい場合、inputタグのtype="file"を使って、パソコン内のデータをアップロードできます。
その際に、
PWAを意識したようなシステムであったり、何かしらのインタラクティブ性の高いWEBサイトの場合、submitした後で、ページのloadingが入ってしまうのがよろしくない場合があります。
そんな時に使えるテクニックを紹介します。
こんな時に使える
1. 画像リストを表示しているようなサイトで画像アップロードをする時に、毎回ページを再ロードされたくない場合。
2. 縦に長い情報量の多いページで、表示編集するような機能を追加して、文中に画像を挿入するような仕様を設けた場合
3. メールサービスのような機能をWEBブラウザで作った場合、添付ファイルなどをデータ送信する場合に、ページをリロードしないようにサーバーにアップロードさせたい場合
ソースコード
下記4ファイルを同じ階層に設置し、phpが利用できる環境でindex.htmlにアクセスすると、アップロードができるようになります。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Data-upload</title>
<script src="upload.js"></script>
</head>
<body>
<button class="data-upload">ファイルをアップロード</button>
<div id="timer"></div>
<script>
var start = (+new Date());
setInterval(function(){
var timer = document.getElementById("timer");
var sec = parseInt(((+new Date()) - start)/100 , 10) / 10;
timer.innerHTML = sec +" sec";
},30);
</script>
</body>
</html>
;(function(){
var custom = {
uploadFileMulti : true, // 複数ファイルアップロード [true:複数ファイル false:単一ファイル]
attribute:{
iframeId:"dataUploadIframe",
inputFileId:"input_file",
inputFileName:"data[]",
buttonName:"data-upload",
actionPath:"./upload.php",
iframeSrc:"./upload.html"
}
};
var $$ = function(){
switch(document.readyState){
case "complete":
this.set();
break;
case "interactive":
this.setEvent(window , "DOMContentLoaded" , $$.prototype.set);
break;
default:
this.setEvent(window , "load" , $$.prototype.set);
break;
}
};
$$.prototype.set = function(){
$$.prototype.setIframe();
$$.prototype.setButton();
};
$$.prototype.setButton = function(){
var buttons = document.getElementsByClassName(custom.attribute.buttonName);
for(i=0; i<buttons.length; i++){
this.setEvent(buttons[i] , "click" , $$.prototype.clickButton);
}
};
$$.prototype.clickButton = function(){
var doc = document.getElementById(custom.attribute.iframeId).contentWindow.document;
var input = doc.getElementById(custom.attribute.inputFileId);
input.click();
};
$$.prototype.setIframe = function(){
var iframe = document.createElement("iframe");
iframe.id = custom.attribute.iframeId;
iframe.style.setProperty("display","none","");
iframe.src = custom.attribute.iframeSrc;
iframe.onload = $$.prototype.makeForm;
document.body.appendChild(iframe);
};
$$.prototype.makeForm = function(e){
var form = document.createElement("form");
form.name = "fm";
form.method = "POST";
form.enctype = "multipart/form-data";
form.action = custom.attribute.actionPath;
this.contentWindow.document.body.appendChild(form);
var inp = document.createElement("input");
inp.id = custom.attribute.inputFileId;
inp.type = "file";
inp.name = custom.attribute.inputFileName;
if(custom.uploadFileMulti === true){
inp.multiple = "multiple";
}
inp.onchange = $$.prototype.dataUpload;
form.appendChild(inp);
};
$$.prototype.dataUpload = function(){
var doc = document.getElementById(custom.attribute.iframeId).contentWindow.document;
var fm = doc.forms[0];
fm.submit();
};
$$.prototype.setEvent = function(target, mode, func){
if (target.addEventListener){target.addEventListener(mode, func, false)}
else{target.attachEvent('on' + mode, function(){func.call(target , window.event)})}
};
new $$;
window.$$UPLOAD = $$;
})();
<?php
namespace UPLOAD;
class PROC{
public static $saveFolder = "upload/";
public static function getRequest(){
self::checkFolder();
$dt = date("YmdHis");
for($i=0,$c=count($_FILES["data"]["tmp_name"]); $i<$c; $i++){
$fileInfo = pathinfo($_FILES["data"]["name"][$i]);
$filePath = self::$saveFolder . $dt."-".$i. "." .$fileInfo["extension"];
move_uploaded_file($_FILES["data"]["tmp_name"][$i] , $filePath);
}
}
public static function checkFolder(){
if(!is_dir(self::$saveFolder)){
mkdir(self::$saveFolder , 0777, true);
return "make";
}
return "exist";
}
}
// echo "-test-";
\UPLOAD\PROC::getRequest();
<html>
<head></head>
<body></body>
</html>
使い方
1. 対象のページに下記2ファイルを設置
upload.js
upload.php
2. HTMLにjsファイルをscriptタグで記述
<script src="upload.js"></script>
3. アップロードを行うボタンを設置
ボタンのclass名に「data-upload」を追加
解説
動作 : アップロードされたファイルは「upload」フォルダが自動で作られてそこに格納されます。
カスタマイズ : デフォルトで複数ファイルのアップデートができるようになっていますが、upload.jsファイルの冒頭customの"uploadFileMulti"をtrueからfalseに切り替えると、単一ファイルだけしかアップロードできなくなります。
0 件のコメント:
コメントを投稿