前端学习(八十三) DOM-文件(Dom)

版权声明: https://blog.csdn.net/zy21131437/article/details/82118439

File对象

最常见的功能就是头像上传,文件预览,文件上传这些类似的功能

input上的type='file',就可以实现选择文件功能

先看一个示例

        <div class="div-a">
            <input type="file" id="file" class="div-input">
            <div class="div-b" id="upfile"></div>
        </div>
        <input type="button" value="上传" id="btn">
        <script>
            let divB=document.getElementById('upfile'),
                fileS=document.getElementById('file'),
                btn=document.getElementById('btn');
            let a=undefined;
            fileS.addEventListener('change',function (params) {
                // console.log(params.target.files);
                a=params.target.files;  //params.target.files获得的是一个类数组flieList对象,有length属性
            })
            btn.addEventListener('click',function(params){
                if(a===undefined){
                    console.log('尚未选择文件');
                }
                else{
                    //异步上传文件
                    //console.log(a[0]);  
                    let fd=new FormData();
                    fd.append('file',a[0], a[0].name);
                    let xhr=new XMLHttpRequest();
                    xhr.open('POST','服务器地址');
                    xhr.send()
                }
            })
        </script>

其中a[0]获得的就是类似于:File(2554) {name: "changelog.txt", lastModified: 1477137622000, lastModifiedDate: Sat Oct 22 2016 20:00:22 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 2554, …}

这边就是定了一个input为file,但是实际开发中不会直接使用这种样式,因此这边简单的修饰了一下,将file因此,在file的下面叠加了一个样式div,选择文件后将目标文件的files属性赋值给a,点击上传后将a上传至服务器

File对象的属性(只读)

属性 说明
lastModified 文件的最近修改时间,从1970年开始的间隔时间
lastModifiedDate 文件的最近修改日期,已经不推荐使用
name 文件名
webkitRelativePath 相对于用户所选择的文件夹路径
size 文件大小,单位是字节
type 文件的MIME类型,比如Image/jpeg

Flie对象的方法

File对象本身没有任何方法,但是Flie对象继承自Blob,Blob有一个方法

Blob.slice([start[,end[,contentType]]])

和File结合使用的对象

FlileList

FileList,可以通过input元素的files属性获得,或者通过Drag和Drop API获取用户拖入到网页中的文件列表

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

加了multiple属性后,用户就可以加入多个文件,这时候的FlieList就是一个类数组的形式,从下标0开始

属性/方法

属性/方法 说明
length 包含的文件个数,只读
item() 根据索引参数,返回对应的文件

Drag和Drop,拖拽事件

名称 作用
dragstart 在拖动时触发
dragend 在拖动完成时触发
dragenter 目标元素上绑定dragenter事件,当拖拽元素进入目标元素时触发
dragover 目标元素上绑定dragover事件, 当拖拽元素在目标元素上移动时触发
drop 目标元素上绑定drop事件, 并同时取消当前目标元素的dragover的默认事件, 当拖拽元素在目标元素上同时鼠标放开时触发事件.
例: box为目标元素.
box.addEventListener('dragover', function(e){console.log('dragover'); e.preventDefault();});
box.addEventListener('drop', function(e){console.log('drop');});
dropdragend同时绑定时drop事件先触发
            let drop = document.querySelector('.drop');
            drop.addEventListener('dragover',function (params) {    /*拖动到目标上方的事件*/
                params.preventDefault();    /*不要执行与事件关联的默认动作*/
                drop.classList.add('over')
            });
            drop.addEventListener('drop',function (params) {    /*拖动到目标位置且松开触发*/
                params.preventDefault();
                drop.classList.remove('over');
                console.log(params.dataTransfer.files); //  输出了一个fileList
            })

FileReader

用来读取文件内容,读取过程是异步的,文件就是FileList的属性值

属性(都是只读)

属性 说明
error 读文件异常时的错误信息
readyState FileReader的状态,数值
result 文件内容

当中关于readyState的取值

属性 说明
FlileReader.EMPTY 0 尚未加载数据
FlieReader.LOADING 1 正在加载数据
FileReader.DONE 2 读取请求已完成

对象的方法

属性 说明
abort 终止读取文件
readAsArrayBuffer 读取的文件内容以ArrayBuffer的形式返回
readAsDataURL 读取的文件以data:URL的形式返回
readAsText 读取的文件内容以纯文本的形式返回
readAsBinaryString(非标准) 读取的文件内容以原始二进制文本的形式返回

对象的事件(也就是可监听的事件)

事件 说明
onabort 终止读取文件时触发
onerror 读取异常时触发
onload 去读成功时触发
onloadstart 开始读取时触发
onloadend 读取完成(可能成功,也可能失败)时触发
onprogress 读取过程中触发

Blob

Blob,二进制大对象,是binary large object 的缩写,是用来存储类似文件的原始数据。

Blob构造函数

var aBlob=new Blob(array[,options])

  • array:数组
  • option:目前纳入规范的只有一个type,也就是类型

例如

            var af=['<a id="a"><div id="b"></div></a>']
            var aBlob=new Blob(af,{type:'text/html'})

方法

silce([start [,end [,contentType]]]):可以切割文件内容,

  • start:起始索引
  • end:结束索引
  • contentType:指定类型

返回值也是一个blob对象,可以使用这个将大文件分割成多个小文件上传,如果上传中断,下次上传使用相同的方法,可以继续上传,但是前段页面一般不用大文件上传,有很多局限

URL

可以用来创建URL对象,也可以用来创建文件对象的临时地址,供用户或开发者使用,比如本地图片预览等

let url=new URL(urlStr,[base])

  • urlStr:url字符串
  • base:如果urlStr是一个相对地址,那么可以指定它的相对目标地址

示例

            var url=new URL('../a','http://www.example.com/dogs')
            console.log(url.hostname);  //www.example.com
            console.log(url.pathname);  // /a

方法

方法 说明
URL.createObjectURL() 创建对象在浏览器中的临时访问地址
URL.revokeObjectURL() 回收使用createObjectURL方法创建的临时访问地址

createObjectURL(object)

接收的是一个参数,最常见的是flle或者Blob,返回的是一个可以在浏览器中访问的地址,这个地址的生命周期是当前窗口,窗口关闭或者刷新就无效了

revokeObjectURL(url)

参数就是创建的url地址,将其回收,节省浏览器的资源

示例:

            var obURL=URL.createObjectURL(object);
            URL.revokeObjectURL(obURL)

实际案例

限制文件的类型

 <input type="file" id="file" class="div-input" accept="image/*">

只要将input中的设置accept属性,就可以限制文件类型(image/*是限制图片类型),accpet接收的是mime类型,多个值以逗号分隔,比如“image/png,image/jpeg”,也可以写文件的后缀名“.png,.jpeg”,也支持通配符*,比如“image/*”

限制文件大小,数量

<input type="file" id="file" class="div-input" accept="image/*" multiple>

只要拿到对象的fileList就可以判断数量和大小

        <div class="div-a">
            <input type="file" id="file" class="div-input" accept="image/*" multiple>
            <div class="div-b" id="upfile"></div>
        </div>
        <input type="button" value="上传" id="btn">
        <script>
            let divB=document.getElementById('upfile')
            fileS.addEventListener('change',function (params) {
                 if(a.length>3){
                        console.log('超出上限了');
                        fileS.value='';
                        return
                    }
                    let exceedSizeFiles=[].slice.call(a).filter(file=>{
                        return file.size > 10*1024;
                    })
                    if(exceedSizeFiles.length){
                        console.log("文件最大为10KB");
                        
                    }
            })
        </script>

文件按钮美化

一种方法是将input隐藏,点击btn时,去关联点击input

        <div class="div-a">
            <input type="file" id="file" class="div-input" accept="image/*" multiple>
            <div class="div-b" id="upfile"></div>
        </div>
        <input type="button" value="上传" id="btn">
        <script>
            let divB=document.getElementById('upfile'),
                fileS=document.getElementById('file'),
                btn=document.getElementById('btn');
            fileS.addEventListener('change',function (params) {
              
            })
            btn.addEventListener('click',function(params){
                fileS.click();
            })
        </script>

另外一种是使用label,通过label的for去关联input

        <div class="div-a">
            <label for="file">点击</label>
            <input type="file" id="file" class="div-input" accept="image/*" multiple>
        </div>
        <input type="button" value="上传" id="btn">
        <script>
            let divB=document.getElementById('upfile'),
                fileS=document.getElementById('file');
            fileS.addEventListener('change',function (params) {
            })
        </script>

label的这种方法可以大大减少关联代码

将文本内容显示到网页上

        <div class="div-a">
            <label for="file">点击</label>
            <input type="file" id="file" class="div-input" accept=".txt" >
        </div>
        <div id="text"></div>
        <script>
            let divB=document.getElementById('text'),
                fileS=document.getElementById('file');
            fileS.addEventListener('change',function (params) {
                var a=new ReadFile();
                a.read(params.target.files[0]);
            })
            function ReadFile(){
                //this.file=file
            }
            ReadFile.prototype={
                constructor:ReadFile,
                read:function(file) {
                    let fr=new FileReader();
                    fr.onload=function(e){
                        document.querySelector('#text').innerHTML = e.target.result;
                    }
                    fr.readAsText(file)
                }
            }
        </script>

将页面上的文本创建文本文件并下载

        <textarea id="textbox">此处输入文本内容</textarea>
        <input type="button" id="create" value="创建文本">
        <a download="info.txt" id="downloadlink" style='display: none'>下载</a>
        <script>
            let textFile = null;
            let makeTextFile=function(text){
                let data= new Blob([text],{type:'text/plain'});
                if(textFile !== null){
                    window.URL.revokeObjectURL(textFile);
                }
                textFile = window.URL.createObjectURL(data);
                return textFile;
            }
            let create = document.getElementById("create");
            let textbox = document.getElementById('textbox');

            create.addEventListener('click',function (){
                let fileUrl = makeTextFile(textbox.value);
                let link = document.getElementById('downloadlink');
                link.href = fileUrl;
                link.click();
            })
        </script>

本地图片预览:FileReader.readAsDataURL

        <input type="file" id="file" accept="image/*">
        <script>
            let fileInput = document.querySelector('#file');
            fileInput.addEventListener('change',e=>{
                showImage(e.target.files[0])
            })
            function showImage(image) {
                let fr = new FileReader();
                fr.onload= function (params) {
                    let img = new Image();
                    img.src = params.target.result;
                    document.body.appendChild(img)
                }
                fr.readAsDataURL(image);
            }
        </script>

猜你喜欢

转载自blog.csdn.net/zy21131437/article/details/82118439