处理 drop 事件
用户在拖拽结束时松开鼠标触发 drop 事件。在 drop 事件里,我们可以通过 event 参数的 DataTransfer 对象获取 files 数据,通过遍历 files 数组可以获取每个文件的信息。然后针对每个文件,创建 HTML 元素来显示缩略图,进度条和文件名称。File 对象的 getAsDataURL 可以将文件内容以 URL 的形式返回,对图片文件来说可以用来显示缩略图。要注意的一点是,在 drop 事件处理函数里要取消事件的继续传播和默认处理函数,结束 drop 事件的处理。清单 10 展示了 drop 事件的处理代码。
清单 10 drop 事件的处理
function handleDrop(event) { // 获取拖拽的文件列表 var files = event.dataTransfer.files; event.stopPropagation(); event.preventDefault(); var fileList = document.getElementById("fileList"); // 展示文件缩略图,文件名和上传进度,上传文件 for (var i = 0; i < files.length; i++) { var file = files[i]; var li = document.createElement('li'); var progressbar = document.createElement('div'); var img = document.createElement('img'); var name = document.createElement('span'); progressbar.className = "progressBar"; img.src = files[i].getAsDataURL(); img.width = 32; img.height = 32; name.innerHTML = file.name; li.appendChild(img); li.appendChild(name); li.appendChild(progressbar); fileList.appendChild(li); uploadFile(file, progressbar) } }
上传文件
我们可以通过 XMLHttpRequest 对象的 sendAsBinary 方法来上传文件,通过侦听 upload 的 progress,load 和 error 事件来监测文件上传的进度,成功完成或是否发生错误。在 progress 事件处理函数里我们通过计算已经上传的比例来确定进度条的位置。参见清单 11。图 4 展示了上传文件的效果图。
清单 11 上传文件
function uploadFile(file, progressbar) { var xhr = new XMLHttpRequest(); var upload = xhr.upload; var p = document.createElement('p'); p.textContent = "0%"; progressbar.appendChild(p); upload.progressbar = progressbar; // 设置上传文件相关的事件处理函数 upload.addEventListener("progress", uploadProgress, false); upload.addEventListener("load", uploadSucceed, false); upload.addEventListener("error", uploadError, false); // 上传文件 xhr.open("POST", "upload.jsp?fileName="+file.name); xhr.overrideMimeType("application/octet-stream"); xhr.sendAsBinary(file.getAsBinary()); } function uploadProgress(event) { if (event.lengthComputable) { // 将进度换算成百分比 var percentage = Math.round((event.loaded * 100) / event.total); console.log("percentage:" + percentage); if (percentage < 100) { event.target.progressbar.firstChild.style.width = (percentage*2) + "px"; event.target.progressbar.firstChild.textContent = percentage + "%"; } } } function uploadSucceed(event) { event.target.progressbar.firstChild.style.width = "200px"; event.target.progressbar.firstChild.textContent = "100%"; } function uploadError(error) { alert("error: " + error); }
本文通过对 File API 规范的讲解,以及两个展示其使用方法的例子,为大家提前揭示了作为未来 HTML5 重要组成部分的 JavaScript File API 的全貌。利用它,结合其他 HTML5 的新特性,比如 Drag&Drop,我们可以利用纯 JavaScript 方案,为用户提供更好使用体验的 Web 应用,与此同时,这样的一致化方案也使我们避免了以往跨浏览器支持所花费的巨大代价。相信 File API 的出现和广泛应用,将会是未来的 Web 2.0 应用的大势所趋。