Detailed explanation of HTML5 drag and drop file upload: Client file processing and asynchronous server upload
Core points
Drag and drop desktop files into the browser is one of the ultimate goals of web application integration. This is the first part of a four-part series of articles, which introduces how to: 1. Enable drag and drop files on web elements; 2. Analyze drag and drop files in JavaScript; 3. Load and parse files on the client; 4. Upload files asynchronously using XMLHttpRequest2; 5. Display graphical progress bars during uploading; 6. Use progressive enhancements to ensure that file upload forms work in any browser (good news for all IE6 fans ! ); 7. Use pure JavaScript code without libraries.
Browser Compatibility Challenge
Before starting, this tutorial involves some of the latest HTML5 technologies, so support is expected to be uneven. The code works now, but the API may change and the browser continues to evolve. - The latest versions of Firefox and Chrome support all features and run perfectly. - Opera can parse files in JavaScript, but does not implement file drag and drop and XMLHttpRequest2 upload. - The desktop versions of IE and Safari do not support any APIs. - Apple has disabled HTML file upload forms on iPhone and iPad versions of Safari. Does anyone know why?
Finally, please note that my code shows the basic concept. There are very few error checks and you need to adjust for your production system.
HTML and CSS
This is a standard form with file input type. The only HTML5 feature is the "multiple" property, which allows the user to select any number of files. We upload files to the server running PHP, but the code is almost the same no matter what technology you use. The hidden MAX_FILE_SIZE value specifies 300,000 bytes - PHP uses this value, but we also check it on the client to prevent uploading large files.
<fieldset><legend>HTML文件上传</legend> <div> <input type="file" id="fileselect" name="fileselect[]" multiple="multiple"> <label for="fileselect">选择要上传的文件:</label> <div id="filedrag">或将文件拖放到此处</div> </div> <input type="submit" value="上传文件" id="submitbutton"> </fieldset> <div id="messages">状态信息</div>
#filedrag { display: none; font-weight: bold; text-align: center; padding: 1em 0; margin: 1em 0; color: #555; border: 2px dashed #555; border-radius: 7px; cursor: default; } #filedrag.hover { color: #f00; border-color: #f00; border-style: solid; box-shadow: inset 0 3px 4px #888; }
We also define a .hover class that changes style when the user drags a file onto an element. The browser will not apply :hover style in this case, but when the event occurs, we can add classes using JavaScript.
File API
W3C file API provides some objects. We will use:- FileList: an array representing the selected file. - File: represents a single file. - FileReader: An interface that allows us to read file data on the client and use it in JavaScript.
Attached JavaScript Event
It's time to start using some JavaScript. We are not using JavaScript library, so to save our typing fingers, we will create several helper functions to return elements by ID and output status messages:
// 通过ID获取元素 function $id(id) { return document.getElementById(id); } // 输出信息 function Output(msg) { var m = $id("messages"); m.innerHTML = msg + m.innerHTML; }
We will now check if the File API is available and call the Init() function:
// 调用初始化文件 if (window.File && window.FileList && window.FileReader) { Init(); } // 初始化 function Init() { var fileselect = $id("fileselect"), filedrag = $id("filedrag"), submitbutton = $id("submitbutton"); // 文件选择 fileselect.addEventListener("change", FileSelectHandler, false); // XHR2是否可用? var xhr = new XMLHttpRequest(); if (xhr.upload) { // 文件拖放 filedrag.addEventListener("dragover", FileDragHover, false); filedrag.addEventListener("dragleave", FileDragHover, false); filedrag.addEventListener("drop", FileSelectHandler, false); filedrag.style.display = "block"; // 移除提交按钮 submitbutton.style.display = "none"; } }
Init() function: 1. Set the "change" event listener for the file input element. 2. Show #filedrag element. 3. Set the "dragover" and "dragleave" event listeners to change the style of #filedrag elements. 4. Set the "drop" event listener for the #filedrag element. 5. Hide the form submission button – since we will analyze and upload the selected file, it is not needed.
You can choose to hide file input elements when supporting file drag and drop. Personally, I prefer to offer both options as drag and drop brings some usability issues. The XMLHttpRequest.upload method check can prevent problems in Opera. The browser supports File, FileList, and FileReader, but does not support drag and drop events or XMLHttpRequest2. So it can display file information, but we don't want to display the #filedrag element or remove the submit button.
File drag and drop style change
Some people have experienced file drag and drop in their web browsers. In fact, experienced web users may think this is impossible. So we used an element that declares "drag and drop files here". We also want to indicate when to drag and drop a file to the #filedrag location by changing its style:
// 文件拖放悬停 function FileDragHover(e) { e.stopPropagation(); e.preventDefault(); e.target.className = (e.type == "dragover" ? "hover" : ""); }
Analyze drag-and-drop or selected files
Whether using "Browse" to select one or more files or drag and drop files to #filedrag location, we use the same FileSelectHandler() function:
// 文件选择 function FileSelectHandler(e) { // 取消事件和悬停样式 FileDragHover(e); // 获取FileList对象 var files = e.target.files || e.dataTransfer.files; // 处理所有File对象 for (var i = 0, f; f = files[i]; i++) { ParseFile(f); } }
This function: 1. Call FileDragHover() to remove the hover style and cancel the browser event. This is crucial, otherwise the browser may try to display the file. 2. Get the FileList object. This will come from the file input box (e.target.files) or the #filedrag element (e.dataTransfer.files). 3. Finally, the function loops through all File objects in the FileList and passes them as parameters to the ParseFile() function...
<fieldset><legend>HTML文件上传</legend> <div> <input type="file" id="fileselect" name="fileselect[]" multiple="multiple"> <label for="fileselect">选择要上传的文件:</label> <div id="filedrag">或将文件拖放到此处</div> </div> <input type="submit" value="上传文件" id="submitbutton"> </fieldset> <div id="messages">状态信息</div>
This function uses three main read-only attributes provided by the File object to output information: -.name: file name (excluding path information) -.type: MIME type, such as image/jpeg, text/plain, etc. -.size : File size (in bytes).
Please view the demo page in Firefox, Chrome, or Opera (no drag and drop support). You can also download files to check the code. We've covered a lot. In my next post, we will learn about How to use HTML5 and JavaScript to open drag-and-drop files…This article has also been translated into Armenian If you like Read this article and you will love Learnable; a place to learn the latest skills and techniques from the masters. Members can instantly access all SitePoint's e-books and interactive online courses, such as real-world HTML5 and CSS3. Comments in this article have been closed. Do you have any questions about HTML5? Why not ask questions on our forum? FAQs about HTML5 file drag and drop *
(The following FAQ part has been omitted due to the length of the article. If necessary, you can request a translation of the FAQ part separately.)
The above is the detailed content of How to Use HTML5 File Drag and Drop. For more information, please follow other related articles on the PHP Chinese website!