分享

Pure HTML5 file upload

 bboyhuiji 2015-01-07
Pure HTML5 file upload

Pure HTML5 file upload

Today we will be developing a great HTML5 file upload form with progress bar and preview (at client-side). We have already gave you jQuery based solution, but today’s application don’t require jQuery at all. All made in pure HTML5 Javascript. I’m going to use FileReader (html5) to implement live preview (without uploading to server), and, going to use XMLHttpRequest to send data to server.

Here are our demo and downloadable package:

Live Demo

Ok, download the sources and lets begin !


Step 1. HTML

At this page you can see out form for upload images

index.html

01<html lang="en" >
02    <head>
03        <meta charset="utf-8" />
04        <title>Pure HTML5 file upload | Script Tutorials</title>
05        <link href="css/main.css" rel="stylesheet" type="text/css" />
06        <script src="js/script.js"></script>
07    </head>
08    <body>
09        <header>
10            <h2>Pure HTML5 file upload</h2>
11            <a href="http://www./pure-html5-file-upload/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
12        </header>
13        <div class="container">
14            <div class="contr"><h2>You can select the file (image) and click Upload button</h2></div>
15 
16            <div class="upload_form_cont">
17                <form id="upload_form" enctype="multipart/form-data" method="post" action="upload.php">
18                    <div>
19                        <div><label for="image_file">Please select image file</label></div>
20                        <div><input type="file" name="image_file" id="image_file" onchange="fileSelected();" /></div>
21                    </div>
22                    <div>
23                        <input type="button" value="Upload" onclick="startUploading()" />
24                    </div>
25                    <div id="fileinfo">
26                        <div id="filename"></div>
27                        <div id="filesize"></div>
28                        <div id="filetype"></div>
29                        <div id="filedim"></div>
30                    </div>
31                    <div id="error">You should select valid image files only!</div>
32                    <div id="error2">An error occurred while uploading the file</div>
33                    <div id="abort">The upload has been canceled by the user or the browser dropped the connection</div>
34                    <div id="warnsize">Your file is very big. We can't accept it. Please select more small file</div>
35 
36                    <div id="progress_info">
37                        <div id="progress"></div>
38                        <div id="progress_percent"> </div>
39                        <div class="clear_both"></div>
40                        <div>
41                            <div id="speed"> </div>
42                            <div id="remaining"> </div>
43                            <div id="b_transfered"> </div>
44                            <div class="clear_both"></div>
45                        </div>
46                        <div id="upload_response"></div>
47                    </div>
48                </form>
49 
50                <img id="preview" />
51            </div>
52        </div>
53    </body>
54</html>

Step 2. CSS

css/main.css

I have selected all necessary styles for our html5 upload form

css/main.css

001.upload_form_cont {
002    background: -moz-linear-gradient(#ffffff, #f2f2f2);
003    background: -ms-linear-gradient(#ffffff, #f2f2f2);
004    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #f2f2f2));
005    background: -webkit-linear-gradient(#ffffff, #f2f2f2);
006    background: -o-linear-gradient(#ffffff, #f2f2f2);
007    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f2f2f2');
008    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f2f2f2')";
009    background: linear-gradient(#ffffff, #f2f2f2);
010 
011    color:#000;
012    overflow:hidden;
013}
014#upload_form {
015    float:left;
016    padding:20px;
017    width:700px;
018}
019#preview {
020    background-color:#fff;
021    display:block;
022    float:right;
023    width:200px;
024}
025#upload_form > div {
026    margin-bottom:10px;
027}
028#speed,#remaining {
029    float:left;
030    width:100px;
031}
032#b_transfered {
033    float:right;
034    text-align:right;
035}
036.clear_both {
037    clear:both;
038}
039input {
040    border-radius:10px;
041    -moz-border-radius:10px;
042    -ms-border-radius:10px;
043    -o-border-radius:10px;
044    -webkit-border-radius:10px;
045 
046    border:1px solid #ccc;
047    font-size:14pt;
048    padding:5px 10px;
049}
050input[type=button] {
051    background: -moz-linear-gradient(#ffffff, #dfdfdf);
052    background: -ms-linear-gradient(#ffffff, #dfdfdf);
053    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #dfdfdf));
054    background: -webkit-linear-gradient(#ffffff, #dfdfdf);
055    background: -o-linear-gradient(#ffffff, #dfdfdf);
056    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#dfdfdf');
057    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#dfdfdf')";
058    background: linear-gradient(#ffffff, #dfdfdf);
059}
060#image_file {
061    width:400px;
062}
063#progress_info {
064    font-size:10pt;
065}
066#fileinfo,#error,#error2,#abort,#warnsize {
067    color:#aaa;
068    display:none;
069    font-size:10pt;
070    font-style:italic;
071    margin-top:10px;
072}
073#progress {
074    border:1px solid #ccc;
075    display:none;
076    float:left;
077    height:14px;
078 
079    border-radius:10px;
080    -moz-border-radius:10px;
081    -ms-border-radius:10px;
082    -o-border-radius:10px;
083    -webkit-border-radius:10px;
084 
085    background: -moz-linear-gradient(#66cc00, #4b9500);
086    background: -ms-linear-gradient(#66cc00, #4b9500);
087    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #66cc00), color-stop(100%, #4b9500));
088    background: -webkit-linear-gradient(#66cc00, #4b9500);
089    background: -o-linear-gradient(#66cc00, #4b9500);
090    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#66cc00', endColorstr='#4b9500');
091    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#66cc00', endColorstr='#4b9500')";
092    background: linear-gradient(#66cc00, #4b9500);
093}
094#progress_percent {
095    float:right;
096}
097#upload_response {
098    margin-top: 10px;
099    padding: 20px;
100    overflow: hidden;
101    display: none;
102    border: 1px solid #ccc;
103 
104    border-radius:10px;
105    -moz-border-radius:10px;
106    -ms-border-radius:10px;
107    -o-border-radius:10px;
108    -webkit-border-radius:10px;
109 
110    box-shadow: 0 0 5px #ccc;
111    background: -moz-linear-gradient(#bbb, #eee);
112    background: -ms-linear-gradient(#bbb, #eee);
113    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #bbb), color-stop(100%, #eee));
114    background: -webkit-linear-gradient(#bbb, #eee);
115    background: -o-linear-gradient(#bbb, #eee);
116    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#bbb', endColorstr='#eee');
117    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#bbb', endColorstr='#eee')";
118    background: linear-gradient(#bbb, #eee);
119}

Step 3. HTML5 JS

js/script.js

001// common variables
002var iBytesUploaded = 0;
003var iBytesTotal = 0;
004var iPreviousBytesLoaded = 0;
005var iMaxFilesize = 1048576; // 1MB
006var oTimer = 0;
007var sResultFileSize = '';
008 
009function secondsToTime(secs) { // we will use this function to convert seconds in normal time format
010    var hr = Math.floor(secs / 3600);
011    var min = Math.floor((secs - (hr * 3600))/60);
012    var sec = Math.floor(secs - (hr * 3600) -  (min * 60));
013 
014    if (hr < 10) {hr = "0" + hr; }
015    if (min < 10) {min = "0" + min;}
016    if (sec < 10) {sec = "0" + sec;}
017    if (hr) {hr = "00";}
018    return hr + ':' + min + ':' + sec;
019};
020 
021function bytesToSize(bytes) {
022    var sizes = ['Bytes', 'KB', 'MB'];
023    if (bytes == 0) return 'n/a';
024    var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
025    return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
026};
027 
028function fileSelected() {
029 
030    // hide different warnings
031    document.getElementById('upload_response').style.display = 'none';
032    document.getElementById('error').style.display = 'none';
033    document.getElementById('error2').style.display = 'none';
034    document.getElementById('abort').style.display = 'none';
035    document.getElementById('warnsize').style.display = 'none';
036 
037    // get selected file element
038    var oFile = document.getElementById('image_file').files[0];
039 
040    // filter for image files
041    var rFilter = /^(image\/bmp|image\/gif|image\/jpeg|image\/png|image\/tiff)$/i;
042    if (! rFilter.test(oFile.type)) {
043        document.getElementById('error').style.display = 'block';
044        return;
045    }
046 
047    // little test for filesize
048    if (oFile.size > iMaxFilesize) {
049        document.getElementById('warnsize').style.display = 'block';
050        return;
051    }
052 
053    // get preview element
054    var oImage = document.getElementById('preview');
055 
056    // prepare HTML5 FileReader
057    var oReader = new FileReader();
058        oReader.onload = function(e){
059 
060        // e.target.result contains the DataURL which we will use as a source of the image
061        oImage.src = e.target.result;
062 
063        oImage.onload = function () { // binding onload event
064 
065            // we are going to display some custom image information here
066            sResultFileSize = bytesToSize(oFile.size);
067            document.getElementById('fileinfo').style.display = 'block';
068            document.getElementById('filename').innerHTML = 'Name: ' + oFile.name;
069            document.getElementById('filesize').innerHTML = 'Size: ' + sResultFileSize;
070            document.getElementById('filetype').innerHTML = 'Type: ' + oFile.type;
071            document.getElementById('filedim').innerHTML = 'Dimension: ' + oImage.naturalWidth + ' x ' + oImage.naturalHeight;
072        };
073    };
074 
075    // read selected file as DataURL
076    oReader.readAsDataURL(oFile);
077}
078 
079function startUploading() {
080    // cleanup all temp states
081    iPreviousBytesLoaded = 0;
082    document.getElementById('upload_response').style.display = 'none';
083    document.getElementById('error').style.display = 'none';
084    document.getElementById('error2').style.display = 'none';
085    document.getElementById('abort').style.display = 'none';
086    document.getElementById('warnsize').style.display = 'none';
087    document.getElementById('progress_percent').innerHTML = '';
088    var oProgress = document.getElementById('progress');
089    oProgress.style.display = 'block';
090    oProgress.style.width = '0px';
091 
092    // get form data for POSTing
093    //var vFD = document.getElementById('upload_form').getFormData(); // for FF3
094    var vFD = new FormData(document.getElementById('upload_form'));
095 
096    // create XMLHttpRequest object, adding few event listeners, and POSTing our data
097    var oXHR = new XMLHttpRequest();       
098    oXHR.upload.addEventListener('progress', uploadProgress, false);
099    oXHR.addEventListener('load', uploadFinish, false);
100    oXHR.addEventListener('error', uploadError, false);
101    oXHR.addEventListener('abort', uploadAbort, false);
102    oXHR.open('POST', 'upload.php');
103    oXHR.send(vFD);
104 
105    // set inner timer
106    oTimer = setInterval(doInnerUpdates, 300);
107}
108 
109function doInnerUpdates() { // we will use this function to display upload speed
110    var iCB = iBytesUploaded;
111    var iDiff = iCB - iPreviousBytesLoaded;
112 
113    // if nothing new loaded - exit
114    if (iDiff == 0)
115        return;
116 
117    iPreviousBytesLoaded = iCB;
118    iDiff = iDiff * 2;
119    var iBytesRem = iBytesTotal - iPreviousBytesLoaded;
120    var secondsRemaining = iBytesRem / iDiff;
121 
122    // update speed info
123    var iSpeed = iDiff.toString() + 'B/s';
124    if (iDiff > 1024 * 1024) {
125        iSpeed = (Math.round(iDiff * 100/(1024*1024))/100).toString() + 'MB/s';
126    } else if (iDiff > 1024) {
127        iSpeed =  (Math.round(iDiff * 100/1024)/100).toString() + 'KB/s';
128    }
129 
130    document.getElementById('speed').innerHTML = iSpeed;
131    document.getElementById('remaining').innerHTML = '| ' + secondsToTime(secondsRemaining);       
132}
133 
134function uploadProgress(e) { // upload process in progress
135    if (e.lengthComputable) {
136        iBytesUploaded = e.loaded;
137        iBytesTotal = e.total;
138        var iPercentComplete = Math.round(e.loaded * 100 / e.total);
139        var iBytesTransfered = bytesToSize(iBytesUploaded);
140 
141        document.getElementById('progress_percent').innerHTML = iPercentComplete.toString() + '%';
142        document.getElementById('progress').style.width = (iPercentComplete * 4).toString() + 'px';
143        document.getElementById('b_transfered').innerHTML = iBytesTransfered;
144        if (iPercentComplete == 100) {
145            var oUploadResponse = document.getElementById('upload_response');
146            oUploadResponse.innerHTML = '<h1>Please wait...processing</h1>';
147            oUploadResponse.style.display = 'block';
148        }
149    } else {
150        document.getElementById('progress').innerHTML = 'unable to compute';
151    }
152}
153 
154function uploadFinish(e) { // upload successfully finished
155    var oUploadResponse = document.getElementById('upload_response');
156    oUploadResponse.innerHTML = e.target.responseText;
157    oUploadResponse.style.display = 'block';
158 
159    document.getElementById('progress_percent').innerHTML = '100%';
160    document.getElementById('progress').style.width = '400px';
161    document.getElementById('filesize').innerHTML = sResultFileSize;
162    document.getElementById('remaining').innerHTML = '| 00:00:00';
163 
164    clearInterval(oTimer);
165}
166 
167function uploadError(e) { // upload error
168    document.getElementById('error2').style.display = 'block';
169    clearInterval(oTimer);
170
171 
172function uploadAbort(e) { // upload abort
173    document.getElementById('abort').style.display = 'block';
174    clearInterval(oTimer);
175}

Most of code is already commented. So I will hope that you will understand all this code. Anyway – how it working: when we select file – function ‘fileSelected’ is executing. We filter all unnecessary formats (allow to upload next formats: bmp, gif, jpg, png, tif), in case of huge file – we will draw warning message. Then, through FileReader::readAsDataURL we will draw live preview of selected file. Plus, we will display another information about image: its name, size, type, and dimensions. Process of uploading is a little complicated. But generally, we have to prepare XMLHttpRequest object, add event listeners to next events: progress, load, error and abort. And after – post form data (I have used FormData class) to our ‘upload.php’ receiver.

Step 4. PHP

upload.php

01<?php
02 
03function bytesToSize1024($bytes, $precision = 2) {
04    $unit = array('B','KB','MB');
05    return @round($bytes / pow(1024, ($i = floor(log($bytes, 1024)))), $precision).' '.$unit[$i];
06}
07 
08$sFileName = $_FILES['image_file']['name'];
09$sFileType = $_FILES['image_file']['type'];
10$sFileSize = bytesToSize1024($_FILES['image_file']['size'], 1);
11 
12echo <<<EOF
13<p>Your file: {$sFileName} has been successfully received.</p>
14<p>Type: {$sFileType}</p>
15<p>Size: {$sFileSize}</p>
16EOF;

As you can see – I’m not uploading file. But, ‘echo’ back all info about accepted file. This information will appear in our <div id="upload_response"></div> element.


Live Demo

Conclusion

Welcome back to read new awesome and unique articles about HTML5. Good luck!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多