HTML5ì DOMì¼ë¡ ì¶ê°ë File API를 ì¬ì©íì¬, ì´ì ì¹ ì»¨í
ì¸ ê° ì¬ì©ììê² ë¡ì»¬ íì¼ì ì íí í íì¼ì 컨í
ì¸ ë¥¼ ì½ëë¡ ìì²í ì ììµëë¤. ì´ ì íì HTML <input>
ì리먼í¸ë ëëê·¸ ì¤ ëëì ì¬ì©íë ê²ì¼ë¡ë ìíí ì ììµëë¤.
ìíì ë¤ë©´ íì¥ ê¸°ë¥ì´ë ë¤ë¥¸ ë¸ë¼ì°ì í¬ë¡¬ ì½ëììë DOM File API를 ì¬ì©íì¤ ì ììµëë¤. íì§ë§, ì¡°ì¬í´ì¼í ëª ê°ì§ ë¶ê°ì ì¸ ê¸°ë¥ë¤ì´ ììì ì ìíì¸ì. ìì¸í ë´ì©ì í¬ë¡¬ ì½ëìì DOM File API ì¬ì©í기 ê¸ì íì¸íì¸ì.
ì íí íì¼ì ì ê·¼í기ë¤ì HTMLì ìê°í´ë´ ìë¤.
<input type="file" id="input" />
File APIë ì¬ì©ìì ìí´ ì íë íì¼ì ëíë´ë ê°ì²´ì¸ File
ì í¬í¨íë FileList
ì ì ê·¼í ì ìê² í´ì¤ëë¤.
ì¬ì©ìê° íëì íì¼ë§ì ì íí ê²½ì°, 리ì¤í¸ì 첫 ë²ì§¸ íì¼ë§ ê³ ë ¤íë©´ ë©ëë¤.
기존ì DOM ì ë í°ë¥¼ ì¬ì©íì¬ ì íë íëì íì¼ì ì ê·¼í기:
const selectedFile = document.getElementById("input").files[0];
change ì´ë²¤í¸ìì ì íí íì¼ì ì ê·¼í기
change
ì´ë²¤í¸ë¥¼ íµí´ FileList
ì ì ê·¼í ìë ììµëë¤(íìë ìëëë¤).
<input type="file" id="input" onchange="handleFiles(this.files)" />
ì¬ì©ìê° íëì íì¼ì ì íí ë, ì¬ì©ìì ìí´ ì íë íì¼ì ëíë´ë ê°ì²´ì¸ File
ì í¬í¨íë FileList
ì í¨ê» handlerFiles()
í¨ìê° í¸ì¶ë©ëë¤.
ì¬ì©ìê° ì¬ë¬ íì¼ì ì íí ì ìëë¡ í길 ìí ê²½ì°, ê°ë¨í input
ì리먼í¸ìì multiple
ìì±ì ì¬ì©íë©´ë©ëë¤.
<input type="file" id="input" multiple onchange="handleFiles(this.files)" />
ì´ ê²½ì°, handleFiles()
í¨ìë¡ ì ë¬ë íì¼ ë¦¬ì¤í¸ë ì¬ì©ìê° ì íí ê° íì¼ì ëí´ íëì File
ê°ì²´ë¥¼ ê°ìµëë¤.
change
ì´ë²¤í¸ 리ì¤ë를 ì¶ê°íë ¤ë©´ EventTarget.addEventListener()
를 ë¤ìê³¼ ê°ì´ ì¬ì©í´ì¼í©ëë¤.
const inputElement = document.getElementById("input");
inputElement.addEventListener("change", handleFiles, false);
function handleFiles() {
const fileList = this.files; /* ì´ì íì¼ ë¦¬ì¤í¸ë¡ ìì
í ì ììµëë¤ */
}
ì´ ê²½ì°ìë, íë¼ë¯¸í°ë¥¼ ì ë¬í ì´ë²¤í¸ í¸ë¤ë¬ììí´ í¸ì¶ë ì´ì ìì ììì ë¬ë¦¬, handleFiles()
í¨ì ìì²´ê° ì´ë²¤í¸ í¸ë¤ë¬ìì ì ìíì¸ì.
DOMì ìí´ ì ê³µë FileList
ê°ì²´ë ì¬ì©ìì ìí´ ì íë 모ë íì¼ì ê°ê° File
ê°ì²´ë¡ ì§ì íì¬ ëì´í©ëë¤. íì¼ ë¦¬ì¤í¸ì length
ìì±ì ê°ì íì¸íì¬ ì¬ì©ìê° ì íí íì¼ì ì를 ê²°ì í ì ììµëë¤.
const numFiles = files.length;
ê°ë³ File
ê°ì²´ë 리ì¤í¸ë¥¼ ê°ë¨í ë°°ì´ì²ë¼ ì ê·¼íì¬ ì»ì ì ììµëë¤.
for (let i = 0, numFiles = files.length; i < numFiles; i++) {
const file = files[i];
..
}
ì ë°ë³µë¬¸ì íì¼ ë¦¬ì¤í¸ì 모ë íì¼ì ìíí©ëë¤.
íì¼ì ëí ì ì©í ì 보를 í¬í¨íë File
ê°ì²´ë ì¸ ê°ì§ ìì±ì ì ê³µí©ëë¤.
name
ì½ê¸° ì ì© ë¬¸ìì´ì¸ íì¼ì ì´ë¦ì ëë¤. ë¨ìí íì¼ ì´ë¦ì´ë©°, ê²½ë¡ì ëí ì ë³´ë í¬í¨íì§ ììµëë¤.
size
ì½ê¸° ì ì© 64ë¹í¸ ì ìì ë°ì´í¸ ë¨ì íì¼ì í¬ê¸°ì ëë¤.
type
ì½ê¸° ì ì© ë¬¸ìì´ì¸ íì¼ì MIME íì
ì
ëë¤. ê²°ì í ì ìë íì
ì¸ ê²½ì° ""
ì
ëë¤.
ë¤ì ììë size
íë¡í¼í°ë¥¼ ì¬ì©íë ë°©ë²ì ë³´ì¬ì¤ëë¤.
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>File(s) size</title>
<script>
function updateSize() {
let nBytes = 0,
oFiles = document.getElementById("uploadInput").files,
nFiles = oFiles.length;
for (let nFileId = 0; nFileId < nFiles; nFileId++) {
nBytes += oFiles[nFileId].size;
}
let sOutput = nBytes + " bytes";
// multiples approximationì ìí ì íì ì½ë
for (
let aMultiples = [
"KiB",
"MiB",
"GiB",
"TiB",
"PiB",
"EiB",
"ZiB",
"YiB",
],
nMultiple = 0,
nApprox = nBytes / 1024;
nApprox > 1;
nApprox /= 1024, nMultiple++
) {
sOutput =
nApprox.toFixed(3) +
" " +
aMultiples[nMultiple] +
" (" +
nBytes +
" bytes)";
}
// ì íì ì½ëì ë
document.getElementById("fileNum").innerHTML = nFiles;
document.getElementById("fileSize").innerHTML = sOutput;
}
</script>
</head>
<body onload="updateSize();">
<form name="uploadForm">
<p>
<input
id="uploadInput"
type="file"
name="myFiles"
onchange="updateSize();"
multiple />
selected files: <span id="fileNum">0</span>; total size:
<span id="fileSize">0</span>
</p>
<p><input type="submit" value="Send file" /></p>
</form>
</body>
</html>
click() ë©ìë를 ì¬ì©íì¬ ì¨ê²¨ì§ íì¼ input ìë¦¬ë¨¼í¸ ì¬ì©í기
ì¸ë ¨ëì§ ìì íì¼ <input>
ì리먼í¸ë¥¼ ì¨ê¸°ê³ íì¼ ì í기를 ì´ê³ ì¬ì©ìì ìí´ ì íë íì¼ ëë íì¼ë¤ì ë³´ì¬ì£¼ë ì¬ë¬ë¶ë§ì ì¸í°íì´ì¤ë¥¼ ì ê³µí ì ììµëë¤. input ì리먼í¸ë¥¼ display:none
ì¼ë¡ ì¤íì¼ë§íê³ <input>
ì리먼í¸ì click()
ë©ìë를 í¸ì¶íë ê²ì¼ë¡ ì´ë¥¼ ìíí ì ììµëë¤.
ë¤ì HTMLì ìê°í´ë´ ìë¤.
<input
type="file"
id="fileElem"
multiple
accept="image/*"
style="display:none"
onchange="handleFiles(this.files)" />
<button id="fileSelect">Select some files</button>
click
ì´ë²¤í¸ë¥¼ ë¤ë£¨ë ì½ëë ë¤ìê³¼ ê°ì ê²ì
ëë¤.
const fileSelect = document.getElementById("fileSelect"),
fileElem = document.getElementById("fileElem");
fileSelect.addEventListener(
"click",
function (e) {
if (fileElem) {
fileElem.click();
}
},
false,
);
ì¬ë¬ë¶ì´ ìíë íì¼ ì í기를 ì´ê¸°ìí ìë¡ì´ ë²í¼ì ì¤íì¼ë§í ì ììµëë¤.
label ì리먼í¸ë¥¼ ì¬ì©íì¬ ì¨ê²¨ì§ íì¼ input ìë¦¬ë¨¼í¸ ì¤íí기JavaScript(click() ë©ìë)를 ì¬ì©íì§ ìê³ íì¼ ì í기를 ì´ëë¡ íì©í기 ìí´ <label>
ì리먼í¸ê° ì¬ì©ë ì ììµëë¤. ì´ ê²½ì°ìë input ì리먼í¸ê° ë°ëì display: none
(ëë visibility: hidden
)ì ì¬ì©íì¬ ì¨ê¸´ìíê° ìëì´ì¼íë©°, ê·¸ë ì§ ìì ê²½ì° ë¼ë²¨ì í¤ë³´ëë¡ ì ê·¼ì´ ë¶ê°íë¤ë ê²ì ì ìíì¸ì. ëì ì¸ê´ìì¼ë¡ ì¨ê¸°ê¸° í
í¬ëì ì¬ì©íì¸ì.
ë¤ì HTMLê³¼
<input
type="file"
id="fileElem"
multiple
accept="image/*"
class="visually-hidden" />
<label for="fileElem">Select some files</label>
CSS를 ìê°í´ë´ ìë¤.
.visually-hidden {
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px, 1px, 1px, 1px);
}
input.visually-hidden:focus + label {
outline: thin dotted;
}
fileElem.click()
ì í¸ì¶í기ìí´ JavaScript ì½ë를 ì¶ê°í íìê° ììµëë¤. ëí ì´ ê²½ì°ìë ì¬ë¬ë¶ì´ ìíëëë¡ label ì리먼í¸ë¥¼ ì¤íì¼ë§ í ì ììµëë¤. ì¬ë¬ë¶ì ì¨ê²¨ì§ input íëì í¬ì»¤ì± ìí를 ìê°ì ì¸ ì í¸(ììì ë³´ì¬ì§ outlineì´ë, background-color ëë box-shadow)ë¡ labelì ì ê³µí´ì¼í©ëë¤. (ì´ ê¸ì ìì± ìì ìì, Firefoxë <input type="file">
ì리먼í¸ì ëí ìê°ì ì í¸ë¥¼ ë³´ì¬ì£¼ì§ ììµëë¤.)
ì¬ì©ìê° íì¼ì ì¹ ì´í리ì¼ì´ì ì¼ë¡ ëëê·¸ ì¤ ëëíëë¡ í ìë ììµëë¤.
첫 ë¨ê³ë ëë ììì ì¤ì íë ê²ì ëë¤. ëëì íì©í 컨í ì¸ ì ì íí ììì ì´í리ì¼ì´ì ì ëìì¸ìë°ë¼ ì주 ë¬ë¼ì§ ì ìì§ë§, ëë ì´ë²¤í¸ë¥¼ ë°ë ì리먼í¸ë¥¼ ë§ëë ê²ì ê°ë¨í©ëë¤.
let dropbox;
dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
ì´ ììììë, dropbox
ë¼ë ID를 ê°ë ì리먼í¸ë¥¼ ëë ììì¼ë¡ ë³ê²½í©ëë¤. dragenter
, dragover
, drop
ì´ë²¤í¸ë¥¼ ìí 리ì¤ë를 ì¶ê°íë ê²ì¼ë¡ ì´ë¥¼ ìíí ì ììµëë¤.
ì°ë¦¬ì ê²½ì°ìë, dragenter
ì dragover
ì´ë²¤í¸ë¡ 무ì¸ê°ë¥¼ ì§ì§ í íìë ìì¼ë¯ë¡, ë í¨ìë 모ë ë¨ìí©ëë¤. ë í¨ìë ë¨ì§ ì´ë²¤í¸ì ì í를 ì¤ë¨íê³ ê¸°ë³¸ ëìì´ ë°ìíë ê²ì ë°©ì§í©ëë¤.
function dragenter(e) {
e.stopPropagation();
e.preventDefault();
}
function dragover(e) {
e.stopPropagation();
e.preventDefault();
}
ì§ì§ ë§ë²ì drop()
í¨ììì ë°ìí©ëë¤.
function drop(e) {
e.stopPropagation();
e.preventDefault();
const dt = e.dataTransfer;
const files = dt.files;
handleFiles(files);
}
ì¬ê¸°ìì, ì°ë¦¬ë ì´ë²¤í¸ë¡ë¶í° dataTransfer
íë를 ì¶ì¶íê³ , ê·¸ë¡ë¶í° íì¼ ë¦¬ì¤í¸ë¥¼ ê°ì ¸ì¨ í, handleFiles()
ë¡ ì ë¬í©ëë¤. ì´ ì§ì ë¶í°, íì¼ì ë¤ë£¨ë ê²ì ì¬ì©ìê° input
ì리먼í¸ë¥¼ ì¬ì©íë ëëê·¸ ì¤ ëëì ì¬ì©íë ëì¼í©ëë¤.
ì¬ë¬ë¶ì´ ì°¨ì¸ë ì¬ì§ ê³µì ì¹ì¬ì´í¸ë¥¼ ê°ë°ì¤ì´ë©° HTML5를 ì¬ì©íì¬ ì¬ì§ì´ ì¤ì ë¡ ì
ë¡ëë기 ì ì ì´ë¯¸ì§ì ì¬ë¤ì¼ 미리보기를 íìí길 ìíë¤ê³ ê°ì í´ë´
ìë¤. ì¬ë¬ë¶ì ìì ì¤ëª
íëë¡ input ì리먼í¸ë ëë ììì ì¤ì íê³ ìëì ê°ì handleFiles()
í¨ì를 í¸ì¶íë©´ë©ëë¤.
function handleFiles(files) {
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (!file.type.startsWith("image/")) {
continue;
}
const img = document.createElement("img");
img.classList.add("obj");
img.file = file;
preview.appendChild(img); // "preview"ê° ê²°ê³¼ë¥¼ ë³´ì¬ì¤ div ì¶ë ¥ì´ë¼ ê°ì .
const reader = new FileReader();
reader.onload = (function (aImg) {
return function (e) {
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
}
}
Hì¬ê¸°ìì ì¬ì©ìê° ì íí íì¼ì ë¤ë£¨ë ë°ë³µë¬¸ì ê° íì¼ì type
ìì±ì ë³´ê³ MIME íì
ì´ "image/
" 문ìì´ë¡ ììíëì§ë¥¼ íì¸í©ëë¤. ì´ë¯¸ì§ì¸ ê° íì¼ì ëí´ìë, ìë¡ì´ img
ì리먼í¸ë¥¼ ìì±í©ëë¤. CSS를 ì¬ì©íì¬ ë³´ê¸° ì¢ì í
ë리ë 그림ì를 ì¤ì í ì ìê³ ì´ë¯¸ì§ì í¬ê¸°ë¥¼ ì§ì í ì ìì¼ë¯ë¡, ì¤íì¼ë§ì ëí´ìë ì¬ê¸°ìì ë¤ë£° íìë ììµëë¤.
ê° ì´ë¯¸ì§ë ê°ê°ì ì¶ê°ë CSS í´ëì¤ obj
를 ê°ì ¸, DOM í¸ë¦¬ììì íìì ë ì½ê²ë§ëëë¤. ê° ì´ë¯¸ì§ì ì´ë¯¸ì§ì ëí File
ì ì§ì íë file
ìì±ë ì¶ê°í©ëë¤(ì´ë ëì¤ì ì¤ì ë¡ ì
ë¡ë를 ìí ì´ë¯¸ì§ë¥¼ fetch í ì ìê²í´ì¤ëë¤). Node.appendChild()
를 ì¬ì©íì¬ ë¤í먼í¸ì 미리보기 ììì ìë¡ì´ ì¬ë¤ì¼ì ì¶ê°í©ëë¤.
ë¤ìì¼ë¡, FileReader
를 ì¤ì íì¬ ì´ë¯¸ì§ ë¡ë©ê³¼ ì´ë¥¼ img
ì리먼í¸ì ì¶ê°íë ê²ì ë¹ë기ì ì¼ë¡ ì²ë¦¬í©ëë¤. ìë¡ì´ FileReader
ê°ì²´ë¥¼ ìì±í íì, onload
í¨ì를 ì¤ì íê³ readAsDataURL()
ì í¸ì¶íì¬ ë°±ê·¸ë¼ì´ëìì ì½ê¸° ìì
ì ììí©ëë¤. ì´ë¯¸ì§ íì¼ì ì ì²´ 컨í
ì¸ ê° ë¡ëëìì ë, onload ì½ë°±ì¼ë¡ ì ë¬ëë data:
URLë¡ ë³íë©ëë¤. ì´ ë£¨í´ì 구ííë©´ img ì리먼í¸ì src ìì±ì ë¡ëë ì´ë¯¸ì§ë¡ ì¤ì íì¬ ì¬ì©ì íë©´ì ì¬ë¤ì¼ì ì´ë¯¸ì§ê° ëíëë©ëë¤.
DOM window.URL.createObjectURL()
ë° window.URL.revokeObjectURL()
ë©ìëì ëí ì§ìì ìê°íìµëë¤. ì´ ë©ìëë¤ì ì¬ì©ìì ì»´í¨í°ì ìë ë¡ì»¬ íì¼ì í¬í¨í´, DOM File
ê°ì²´ë¥¼ ì¬ì©í´ 참조ë ë°ì´í°ì ëí ì°¸ì¡°ë¡ ì¬ì©í ì ìë ê°ë¨í URL 문ìì´ì ìì±í ì ìê² í´ì¤ëë¤.
HTMLì URLë¡ ì°¸ì¡°í길 ìíë File
ê°ì²´ê° ìë¤ë©´, ë¤ìê³¼ ê°ì´ ê°ì²´ URLì ìì±í ì ììµëë¤.
const objectURL = window.URL.createObjectURL(fileObj);
ê°ì²´ URLì File
ê°ì²´ë¥¼ ìë³íë 문ìì´ì
ëë¤. window.URL.createObjectURL()
ì í¸ì¶í ëë§ë¤, ì¬ë¬ë¶ì´ ì´ë¯¸ í´ë¹ íì¼ì ëí ê°ì²´ URLì ìì±íëë¼ë ê³ ì í ê°ì²´ URLì´ ìì±ë©ëë¤. ê°ê°ì ë°ëì í´ì ëì´ì¼ í©ëë¤. ê°ì²´ URLì ë¤í먼í¸ê° unloadë ë ìëì¼ë¡ í´ì ëì§ë§, ì¬ë¬ë¶ì íì´ì§ê° ëì ì¼ë¡ ì´ë¥¼ ì¬ì©í ê²½ì° window.URL.revokeObjectURL()
ì í¸ì¶íì¬ ëª
ìì ì¼ë¡ í´ì í´ì¼í©ëë¤.
window.URL.revokeObjectURL(objectURL);
ìì: ê°ì²´ URLì ì¬ì©íì¬ ì´ë¯¸ì§ íìí기
ë¤ì ììë ê°ì²´ URLì ì¬ì©íì¬ ì´ë¯¸ì§ ì¬ë¤ì¼ì íìí©ëë¤. ë¶ê°ì ì¼ë¡, íì¼ì ì´ë¦ê³¼ í¬ê¸°ë¥¼ í¬í¨í ë¤ë¥¸ ì ë³´ë íìí©ëë¤.
ì¸í°íì´ì¤ë¥¼ ëíë´ë HTMLì ë¤ìê³¼ ê°ìµëë¤.
<input
type="file"
id="fileElem"
multiple
accept="image/*"
style="display:none"
onchange="handleFiles(this.files)" />
<a href="#" id="fileSelect">Select some files</a>
<div id="fileList">
<p>No files selected!</p>
</div>
ì ì½ëë íì¼ ì í기를 ë¶ë¬ì¤ë ë§í¬ì ì°ë¦¬ì íì¼ <input>
ì리먼í¸ë¥¼ ì¤ì í©ëë¤(íì¼ inputì ì¨ê²¨ ë ë§¤ë ¥ì ì¸ ì¬ì©ì ì¸í°íì´ì¤ê° íìëë ê²ì ë°©ì§íìì¼ë¯ë¡). ì´ë íì¼ ì í기를 ë¶ë¬ì¤ë ë©ìëì ë§ì°¬ê°ì§ë¡, Using hidden file input elements using the click() method ì¹ì
ìì ì¤ëª
í©ëë¤.
handleFiles()
ë©ìëë ë¤ìê³¼ ê°ìµëë¤.
window.URL = window.URL || window.webkitURL;
const fileSelect = document.getElementById("fileSelect"),
fileElem = document.getElementById("fileElem"),
fileList = document.getElementById("fileList");
fileSelect.addEventListener(
"click",
function (e) {
if (fileElem) {
fileElem.click();
}
e.preventDefault(); // "#" í´ìë¡ ì´ëì ë°©ì§
},
false,
);
function handleFiles(files) {
if (!files.length) {
fileList.innerHTML = "<p>No files selected!</p>";
} else {
fileList.innerHTML = "";
const list = document.createElement("ul");
fileList.appendChild(list);
for (let i = 0; i < files.length; i++) {
const li = document.createElement("li");
list.appendChild(li);
const img = document.createElement("img");
img.src = window.URL.createObjectURL(files[i]);
img.height = 60;
img.onload = function () {
window.URL.revokeObjectURL(this.src);
};
li.appendChild(img);
const info = document.createElement("span");
info.innerHTML = files[i].name + ": " + files[i].size + " bytes";
li.appendChild(info);
}
}
}
fileList
IDë¡ <div>
ì URLì íì¹íë ê²ì¼ë¡ ììí©ëë¤. ì´ë ì¬ë¤ì¼ì í¬í¨íì¬ íì¼ ë¦¬ì¤í¸ë¡ ì½ì
íë ë¸ë¡ì
ëë¤.
handleFiles()
ë¡ ì ë¬ë FileList
ê°ì²´ê° null
ì¸ ê²½ì°, ë¸ë¡ì inner HTMLì ê°ë¨íê² "No files selected!"를 íìíëë¡ ì¤ì í©ëë¤. null
ì´ ìë ê²½ì°, ë¤ìê³¼ ê°ì´ íì¼ ë¦¬ì¤í¸ë¥¼ 구ì¶í©ëë¤.
<ul>
) ì리먼í¸ê° ìì±ë©ëë¤.Node.appendChild()
ë©ìë í¸ì¶ì ìí´ <div>
ë¸ë¡ì¼ë¡ ì½ì
ë©ëë¤.files
ì ìí´ ëíëë FileList
ë´ì ê° File
ì ëí´ :
<li>
) ì리먼í¸ë¥¼ ìì±íê³ ë¦¬ì¤í¸ë¡ ì½ì
í©ëë¤.<img>
) ì리먼í¸ë¥¼ ìì±í©ëë¤.window.URL.createObjectURL()
ì ì¬ì©íì¬ ì´ë¯¸ì§ì ìì¤ë¥¼ íì¼ì ëíë´ë ìë¡ì´ ê°ì²´ URLë¡ ì¤ì í´ blob URLì ìì±í©ëë¤.window.URL.revokeObjectURL()
ë©ìë를 í¸ì¶íê³ img.src
ë¡ ì§ì í ê°ì²´ URL 문ìì´ì ì ë¬íë©´ë©ëë¤.ë¤ìì ì ì½ëì ë¼ì´ë¸ ë°ëª¨ì ëë¤.
Example: Uploading a user-selected fileAnother thing you might want to do is let the user upload the selected file or files (such as the images selected using the previous example) to a server. This can be done asynchronously very easily.
Creating the upload tasksContinuing with the code that built the thumbnails in the previous example, recall that every thumbnail image is in the CSS class obj
with the corresponding File
attached in a file
attribute. This allows us to select all of the images the user has chosen for uploading using Document.querySelectorAll()
, like this:
function sendFiles() {
const imgs = document.querySelectorAll(".obj");
for (let i = 0; i < imgs.length; i++) {
new FileUpload(imgs[i], imgs[i].file);
}
}
Line 2 fetches a NodeList
, called imgs
, of all the elements in the document with the CSS class obj
. In our case, these will be all of the image thumbnails. Once we have that list, it's trivial to go through it and create a new FileUpload
instance for each. Each of these handles uploading the corresponding file.
The FileUpload
function accepts two inputs: an image element and a file from which to read the image data.
function FileUpload(img, file) {
const reader = new FileReader();
this.ctrl = createThrobber(img);
const xhr = new XMLHttpRequest();
this.xhr = xhr;
const self = this;
this.xhr.upload.addEventListener(
"progress",
function (e) {
if (e.lengthComputable) {
const percentage = Math.round((e.loaded * 100) / e.total);
self.ctrl.update(percentage);
}
},
false,
);
xhr.upload.addEventListener(
"load",
function (e) {
self.ctrl.update(100);
const canvas = self.ctrl.ctx.canvas;
canvas.parentNode.removeChild(canvas);
},
false,
);
xhr.open(
"POST",
"https://demos.hacks.mozilla.org/paul/demos/resources/webservices/devnull.php",
);
xhr.overrideMimeType("text/plain; charset=x-user-defined-binary");
reader.onload = function (evt) {
xhr.send(evt.target.result);
};
reader.readAsBinaryString(file);
}
The FileUpload()
function shown above creates a throbber, which is used to display progress information, and then creates an XMLHttpRequest
to handle uploading the data.
Before actually transferring the data, several preparatory steps are taken:
XMLHttpRequest
's upload progress
listener is set to update the throbber with new percentage information so that as the upload progresses the throbber will be updated based on the latest information.XMLHttpRequest
's upload load
event handler is set to update the throbber progress information to 100% to ensure the progress indicator actually reaches 100% (in case of granularity quirks during the process). It then removes the throbber since it's no longer needed. This causes the throbber to disappear once the upload is complete.XMLHttpRequest
's open()
method to start generating a POST request.XMLHttpRequest
function overrideMimeType()
. In this case, we're using a generic MIME type; you may or may not need to set the MIME type at all depending on your use case.FileReader
object is used to convert the file to a binary string.XMLHttpRequest
function send()
is called to upload the file's content.This example, which uses PHP on the server side and JavaScript on the client side, demonstrates asynchronous uploading of a file.
<?php
if (isset($_FILES['myFile'])) {
// Example:
move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
exit;
}
?><!DOCTYPE html>
<html>
<head>
<title>dnd binary upload</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="application/javascript">
function sendFile(file) {
const uri = "/index.php";
const xhr = new XMLHttpRequest();
const fd = new FormData();
xhr.open("POST", uri, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText); // handle response.
}
};
fd.append('myFile', file);
// Initiate a multipart/form-data upload
xhr.send(fd);
}
window.onload = function() {
const dropzone = document.getElementById("dropzone");
dropzone.ondragover = dropzone.ondragenter = function(event) {
event.stopPropagation();
event.preventDefault();
}
dropzone.ondrop = function(event) {
event.stopPropagation();
event.preventDefault();
const filesArray = event.dataTransfer.files;
for (let i=0; i<filesArray.length; i++) {
sendFile(filesArray[i]);
}
}
}
</script>
</head>
<body>
<div>
<div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
</div>
</body>
</html>
Example: Using object URLs to display PDF
Object URLs can be used for other things than just images! They can be used to display embedded PDF files or any other resources that can be displayed by the browser.
In Firefox, to have the PDF appear embedded in the iframe (rather than proposed as a downloaded file), the preference pdfjs.disabled
must be set to false
ë¹íì¤ .
<iframe id="viewer"></iframe>
And here is the change of the src
attribute:
const obj_url = window.URL.createObjectURL(blob);
const iframe = document.getElementById("viewer");
iframe.setAttribute("src", obj_url);
window.URL.revokeObjectURL(obj_url);
Example: Using object URLs with other file types
You can manipulate files of other formats the same way. Here is how to preview uploaded video:
const video = document.getElementById("video");
const obj_url = window.URL.createObjectURL(blob);
video.src = obj_url;
video.play();
window.URL.revokeObjectURL(obj_url);
See also
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4