h5 - File API

File

1、作用:可以读取本地文件内容;

2、操作方式:通过<input type="file"> 或 通过拖拽来选择本地文件。

3、使用:

监听input的change 事件,在事件对象中的target里,有个files属性,值是一个类对象,里边装的就是文件的一些信息,分别是:

name:文件名称,只读字符串。

size:以字节数为单位的文件大小。

type:文件的MIME类型,只读字符串,档类型不确定时,为 ""。(相当于文件类型)

<input id="file" type="file">
<script>
    let f = document.getElementById('file')
    f.addEventListener('change', (e) => {
        console.log(e.target.files[0])
    })
</script>

 

4、多文件上传,在标签上添加 nultiple 属性即可

<input id="file" type="file" multiple>

 

封装上传文件,返回文件大小类型及名称

<input id="file" type="file" multiple>
<script>
    function formatSize(bytes) {
        const GB = Math.pow(1024, 4)
        const M = Math.pow(1024, 2)
        const KB = Math.pow(1024, 1)
        if (bytes >= GB) {
            return (bytes / GB).toFixed(2) + 'GB'
        } else if (bytes >= M) {
            return (bytes / M).toFixed(2) + 'M'
        } else if (bytes >= KB) {
            return (bytes / KB).toFixed(2) + 'KB'
        }
    }
    let file = document.getElementById('file')
    file.addEventListener('change', (e) => {
        let arr = []
        let len = e.target.files['length']
        let files = e.target.files
        for(let i = 0; i <len; i ++) {
            let obj = {}
            obj['size'] = formatSize(files[i]['size'])
            obj['name'] = files[i]['name']
            obj['type'] = files[i]['type']
            arr.push(obj)
            obj = {}
        }
    })
</script>

 

5、样式重写

相信大家已经看出来了,上传文件自带的样式非常丑陋,下边提供两种方式改写样式:

方式一:

思路:文件上传样式display:none; 点击别的元素,在处理函数中去触发文件上传的点击事件

<input id="file" type="file" style="display: none" onchange="handleFile(this.files)">
<button id="btn">上传文件</button>
<script>
    let file = document.getElementById('file')
    let btn = document.getElementById('btn')
    // input 的onchange事件的处理函数
    function handleFile(files) {
        console.log('files', files)
    }
    // 点击按钮
    btn.addEventListener('click', () => {
        if (file) {
            file.click() // 触发input的点击事件,从而会吊起文件上传
        }
        e.preventDefault() // 阻止默认事件
    })
</script>

 

方式二:

不使用js(click方法)来唤起文件上传窗口,使用 <label> 元素.

可以为 label 添加 样式

<style>
    #file{
        position: absolute;!important;
        height: 1px;
        width: 1px;
        overflow: hidden;
        /* 裁剪一个【绝对定位】的元素, rect (top, right, bottom, left)*/
        clip: rect(1px, 1px, 1px, 1px);
    }
    /* outline:thin dotted 替换其默认focus时的样式
    */
    input#file:focus{
        outline: thin dotted;
    }
</style>
<input id="file" type="file" multiple>
<label for="file">上传文件</label>
<script>
    let file = document.getElementById('file')
    file.addEventListener('change', (e) => {
        console.log('e', e)
    })
</script>

 

拖拽上传:

思路:H5的拖动监听事件:

(1)drapenter - 当拖拽元素进入放置目标时触发。

(2)drapover -  当拖拽元素在放置目标中移动时触发,类似mouseover

(3)drap - 当拖拽元素放置在目标时触发(拖拽元素放置在目标元素之后,直接触发input的onchange事件,即可完成拖拽上传)

<div class="box">拖拽上传</div>
<input style="display: none;" type="file" id="file" onchange="handleFile">
<script>
    let dropbox = document.getElementsByClassName('box')[0]
    // 拖拽完成之后触发
    function handleFile(e) {
        console.log('file', e)
    }
    // 阻止默认事件 及 冒泡
    function dragenter(e) {
        e.stopPropagation()
        e.preventDefault()
    }
    // 阻止默认事件 及 冒泡
    function dragover(e) {
        e.stopPropagation()
        e.preventDefault()
    }
    // 元素放置目标元素时的处理函数,事件对象e中有一个dataTransfer对象,里边files字段
    // 就是文件信息列表,再将它传给handleFiles()函数,在这之后跟文件点击上传一样了。
    function drop(e) {
        e.stopPropagation()
        e.preventDefault()
        let dt = e.dataTransfer
        let files = dt.files
        handleFile(files)
    }
    dropbox.addEventListener("dragenter", dragenter, false)
    dropbox.addEventListener("dragover", dragover, false)
    dropbox.addEventListener("drop", drop, false)
</script>

 

FileReader

1、定义:

FileReader 对象允许web应用程序异步的读取本地电脑上的文件,使用File或blob对象指定读取的文件或数据。

用大白话讲:fileReader可以读取指定文件的信息包含文件名、大小、类型、修改时间 等等 ,读取的意图用来传给后台、或者显示图片缩略图 等等· · ·

File对象: 指的是用户点击文件上传返回的 FileList 对象,或者 用户拖拽生成的 DataTransfer对象。

let fileRd = new FileReader()
console.log(fileRd)

 

2、属性 - 只读

(1) fileRd.error - 表示读取文件时发生的错误

(2) fileRd.readyState - 表示 fileRd状态的数字 ,如下:

      0:换没有加载任何数据

      1:数据正在被加载

      2:已完成全部的读取请求

(3) fileRd.result - 文件的内容,该属性读取操作完成后才有效。

 

3、常用事件处理函数

fileRd.onabort - 处理abort事件,该事件在读取操作被中断时,触发。

fileRd.onload - 处理load事件,改时间在读取完成时触发。

 

4、方法

fileRd.abort( ) - 终止读取操作,再返回时,readyState属性为DONE

fileRd.readAsArrayBuffer( ) - 开始读取指定的Blob中的内容,一旦读取完成,result属性中将包含所读取文件的原始二进制数据。

fileRd.readAsDataURL( ) - 开始读取指定的Blob中的内容,一旦读取完成,result属性中将包含一个data:URL格式的Base64字符串,以表示读取的内容。

fileRd.readAsText( ) - 开始读取指定的Blob中的内容,一旦读取完成,result属性中将包含字符串,以表示所读取的文件内容。

 

看到这里,先来解释一波吧,之前没使用过的应该看晕了O(∩_∩)O哈哈~:

上边几个属性、处理函数、方法使用最多的是 

fileRd.readAsDataURL( )读取一个文件对象(通常读取图片格式的较多,目的转base64),这个文件对象是用户点击文件上传之后,通过事件对象e获取的,上边有好多例子,不啰嗦了!读取完之后呢,会被fileRd.onload监听到,在onload事件处理函数的参数ProgressEvent对象中可以获取到读取的结果,来来,看个小例子:

<input type="file" id="file">
<script>
 let file = document.getElementById('file')
 // 监听文件上传
 file.addEventListener('change', (e) => {
    const files = e.target.files[0]
    // new 一个文本文件读取的对象
    let render = new FileReader()
    // 监听读取完成的处理函数
    render.onload = function(fileEvent) {
        console.log('e', fileEvent) // 来来看下它的样子
        console.log(fileEvent.target.result) // 这个就是读取的结果
    }
    // 把文件读取为base64格式
    render.readAsDataURL(files)
 })
</script>

 

先来看下上边 fileEvent 对象的样子:

在看看读取结果的样子:

之前做图片上传的朋友应该很熟悉,这个就是base64格式,可以直接赋值给img标签的scr属性:

 

好了说到这基本结束了,以后会及时更新以及加一些小案例。

再举个栗子吧,加深印象:

显示用户上传的图片缩略图:

看完上边说的这些,这个需求很简单:

<input type="file" id="file">
<div id="img-box"></div>
<div class="file-name"></div>
<div class="file-type"></div>
<div class="file-size"></div>
<script>
    // size转KB、M、GB
    function formatSize(bytes) {
        const GB = Math.pow(1024, 4)
        const M = Math.pow(1024, 2)
        const KB = Math.pow(1024, 1)
        if (bytes >= GB) {
            return (bytes / GB).toFixed(2) + 'GB'
        } else if (bytes >= M) {
            return (bytes / M).toFixed(2) + 'M'
        } else if (bytes >= KB) {
            return (bytes / KB).toFixed(2) + 'KB'
        }
    }
    let file = document.getElementById('file'),
        imgBox = document.getElementById('img-box'),
        fileType = document.getElementsByClassName('file-type')[0],
        fileSize = document.getElementsByClassName('file-size')[0],
        fileName = document.getElementsByClassName('file-name')[0];
    // 监听文件上传
    file.addEventListener('change', (e) => {
        let img = new Image()
        let files = e.target.files[0]
        let render = new FileReader()
        render.onload = (ev) => {
            img.src = ev.target.result
            imgBox.appendChild(img)
            fileType.innerText = `图片类型: ${files['type']}`
            fileSize.innerText = `图片大小: ${formatSize(files['size'])}`
            fileName.innerText = `图片名字: ${files['name']}`
        }
        render.readAsDataURL(files)
    })
</script>

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值