文件上传之本地预览

本文主要介绍了HTML5中的File API,包括FileList、File和FileReader对象,详细阐述了如何实现文件的本地预览,包括文本文件和图片文件的预览,并探讨了文件拖拽预览的实现方法。同时提供了完整的代码示例和相关参考文献链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件上传之本地预览

标签(空格分隔): fileupload html javascript


概述

文件上传需要使用input[type=”file”],如下:

<input type="file" name="upload" mutipart accept="image/*">
<!--
    ** 可用属性 **
    type: file(必填),必须为file
    multipart: 指示是否可以多选
    accept : 指示文件类型,指示可选择的文件,使用逗号(,)分隔
        可能的值为:
        * 后缀,如.jpg,.png
        * 一个有效的MIME type
        * audio/* 音乐文件
        * video/* 视频文件
        * image/* 图片文件
-->

通过使用js的files属性获取一个FileList实例,FileList是一个伪数组,可以通过fileList[i]以及fileList.item(i)获取File实例。File实例包括一些文件的基本属性,通过FileReader获取文件的内容。

File API

FileList

文件列表,通过files属性获取一个FileList实例。
属性&方法

fileList.item(index),获取指定索引的File对象。
fileList[index],获取指定索引的File对象。
fileList.length,获取list的长度

代码参考

// fileInput是一个 HTML input 元素: <input type="file" id="myfileinput" multiple>
var fileInput = document.getElementById("myfileinput");
// files 是一个 FileList 对象(类似于NodeList对象)
var files = fileInput.files;
var file;
//遍历所有文件
for (var i = 0; i < files.length; i++) {
    // 取得一个文件
    file = files.item(i);
    // 这样也行
    file = files[i];
    // 取得文件名
    alert(file.name + file.size + file.type);
}

File

文件对象,使用input[type=”file”]添加的文件,每一个文件对应一个File对象,可以用过input.files[index]获取。
属性&方法

name DOMString 表示文件的名称,只读(对于早期版本的Gecko,使用fileName)
size unsigned long long 表示文件的大小,只读(对于早期版本的Gecko,使用fileSize)
type DOMString 文件的MIME类型,只读

代码样例

参见FileList

FileReader

使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要处理的文件或数据.其中File对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后的返回结果.
属性&方法

var reader = new FileReader()
abort()
readAsArrayBuffer(in Blob blob);
readAsBinaryString(in Blob blob);
readAsDataURL(in Blob blob);
readAsText(in Blob blob, [optional] in DOMString encoding),在缺省的情况下,使用UTF-8编码。

error DOMError 在读取文件是发生的错误,只读
readState unsigned short 表明FileReader对象当前的状态,只读(参加状态
result jsvar, 该值根据reader调用的方法不同而不同,参数类型如下:
* readAsArrayBuffer, result对应ArrayBuffer对象;
* readAsBinaryString, result对应一个包含所读文件的原始二进制数据;
* readAsDataURL,result对应一个字符串的URL资源。
* readAsText,result对应一个字符串,其中返回字符串按照encoding编码。

状态
EMPTY 0 还没有加载任何数据
LOADING 1 数据正在被加载
DONE 2 已完成全部的数据请求

文件本地预览

下面介绍两种文件预览的方式,可以分别预览文本文件和图片文件。

文本

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件预览</title>
</head>
<body>
    <div>
        <input type="file" name="fileupload" id="upload" multiple>
    </div>
    <div id="previews"></div>
    <script type="text/javascript">
        // ... 此处省略代码
    </script>
</body>
</html>
window.addEventListener("load", function(){
    var fileinput = document.getElementById("upload");
    var previews = document.getElementById("previews");
    if(fileinput){
        fileinput.addEventListener("change", function(e){
            var files = this.files;
            var str = "";
            if(files && files.length > 0){
                previews.innerHTML = "";
                for(var i=0; i<files.length; i++){
                    var item = files[i];
                    var div = document.createElement("div");
                    onHandleItem(item, div);
                    previews.appendChild(div);
                }
            }
            else{
                previews.innerHTML = "";
            }
        }, false);
    }
}, false);
function onHandleItem(file, parent){
    var textarea = document.createElement("textarea");
    var reader = new FileReader();
    textarea.readOnly = true;
    textarea.rows = 30;
    textarea.cols = 100;
    parent.appendChild(textarea);

    reader.onerror = function(){

    }
    reader.onload = function(e){
        textarea.value = e.target.result;
    }
    reader.readAsText(file);
}

代码分析

  1. 通过reader.readAsText讲文本文件中的内容以字符串的形式读取到内存,并赋值给reader.result属性。
  2. 通过将textarea的value值设置为reader.result

效果预览
image_1anci144r50dq0ci8q18eboe4m.png-74.7kB

图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图片预览</title>
</head>
<body>
<input type="file" id="upload" name="upload" onchange="handleFiles(this.files);" multiple accept="image/*"><br />
<div id="preview"></div>
<script type="text/javascript">
    // 省略js代码
</script>
</body>
</html>
function handleFiles(files){
    var preview = document.getElementById("preview");
    // 清空 file.
    preview.innerHTML = "";
    for (var i = 0; files && i < files.length; i++) {
        var file = files[i];
        var imageType = /^image\//;

        if ( !imageType.test(file.type) ) {
          continue;
        }

        var img = document.createElement("img");
        img.style.display = "block";
        img.file = file;
        // 假设 "preview" 是将要展示图片的 div
        preview.appendChild(img);

        var reader = new FileReader();
        reader.onload = (function(aImg) { 
          return function(e) { 
            aImg.src = e.target.result; 
          }; 
        })(img);
        reader.readAsDataURL(file);
  }
}

代码分析

本代码的核心是使用readAsDataURL将file对象中的数据通过base64的格式体现出来。

效果预览
image_1anchtnf8btbofj15c6h7k10fr9.png-3.4kB

文件拖拽

文件拖拽是指直接通过拖拽的方式实现文件上传/预览。如将windows资源管理器中的某一个文件拖入浏览器的某一个区域,实现文件预览。下面我们实现拖拽预览功能。

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>拖拽预览</title>
    <style>
        body{
            padding-top: 10px;
        }
        #dragArea{
            height: 300px;
            width: 500px;
            margin: 0 auto;
            text-align: center;
            line-height: 300px;
            cursor: pointer;
            border: solid 1px black;
        }
        #dragArea i{
            font-weight: bold;
            font-style: normal;
        }
        #showArea{
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div id="dragArea">
        <i>+</i>
        <span>拖拽文件至该区域</span>
    </div>
    <div id="preview"></div>
    <script type="text/javascript">
        // 此处省略js代码
    </script>
</body>
</html>
window.addEventListener("load", function(){
    var dragArea = document.getElementById("dragArea");
    var dragenter = function(e){
        e.stopPropagation();
        e.preventDefault();
    }, dragover = function(e){
        e.stopPropagation();
        e.preventDefault();
    }, drop = function(e){
        e.stopPropagation();
        e.preventDefault();
        if(!e.dataTransfer){
            return true;
        }
        var dt = e.dataTransfer;
        var files = dt.files;
        handleFiles(files);
    };

    dragArea.addEventListener("dragenter", dragenter, false);
    dragArea.addEventListener("dragover", dragover, false);
    dragArea.addEventListener("drop", drop, false);
}, false);
// handleFiles参照图片预览

代码分析

  • 通过event的dataTransfer属性获取当前drag的文件;
  • 阻止浏览器默认事情,默认事件为下载该文件;
  • handleFiles的逻辑与图片预览保持一直即可。

更多
对于本例,如果单纯的一个拖拽,用起来肯定是别扭的,最好能加上点击区域时启动文件选择框,我们分别在html和js中添加如下代码:

<input type="file" id="file" style="display:none;" multiple accept="image/*">
window.addEventListener("load", function(e){
    ...
    var file = document.getElementById("file");
    dragArea.addEventListener("click", function(){
        file.click();
    }, false);
    file.addEventListner("change", function(e){
        if(this.files && this.files.length > 0){
            handleFiles(this.files);    
        }
    }, false);
    ...
}, false);

效果预览
image_1ancqudoorbt13d5nri173162u13.png-130.5kB

代码地址

https://coding.net/u/shushanfx/p/FromWebFront/git/tree/master/file_preview

参考文献

  1. 在Web应用中使用文件: https://developer.mozilla.org/zh-CN/docs/Using_files_from_web_applications
  2. FileList: https://developer.mozilla.org/zh-CN/docs/Web/API/FileList
  3. FileReader: https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
  4. File: https://developer.mozilla.org/zh-CN/docs/Web/API/File
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值