手机版

JS实现表单多文件上传风格美化 支持选择文件后删除相关项

时间:2021-09-07 来源:互联网 编辑:宝哥软件园 浏览:

开发中经常涉及到文件上传的需求,根据不同的业务需求有不同的文件上传情况。

有简单的单个文件上传和多个文件上传。因为浏览器的原生文件上传风格和功能支持度都不是太高,我们经常美化风格,完善功能。

通过一个实例,对多个文件的上传风格做了一些简单的美化。),同时支持选择文件后删除相关文件,最后上传

文章很长,让我们简单看一下图表:

一、文件上传的依据

1.单个文件上传

最简单的文件上传是单文件上传。enctype='multipart/form-data '被添加到表单标记中,表单中有一个输入[type='file']项

表单名称='form1 '方法='post '操作='/ABC . PHP ' enctype=' multipart/Form-data '输入类型=' text '名称=' user' id=' user '占位符='请输入昵称'输入类型=' file '名称=' user image' id=' user image '输入类型=' submit '名称=' sub '值=' submit' /form2。多个文件

1)类似于单文件上传,简单的多文件上传实际上是多输入几个[type='file']

表单名称='form1 '方法='post '操作='/ABC . PHP ' enctype=' multipart/Form-data '输入类型=' text '名称=' user' id=' user '占位符='请输入昵称'输入类型=' file '名称=' userimage1' id=' userimage1 '输入类型=' file '名称=' userima。ge2 ' id=' user image 2 ' input type=' file ' name=' user image 3 ' id=' user image 3 ' input type=' sub ' name=' sub ' value=' submit '/form 2)html 5为表单文件项添加了一个多重属性,可用于设置和选择多个文件,例如

表单名称='form1 '方法='post '操作='/ABC . PHP ' enctype=' multipart/Form-data '输入类型=' text '名称=' user' id=' user '占位符='请输入昵称'输入类型=' file '名称=' user image' id=' user image '多重输入类型=' submit '名称=' sub '值=' submit' /form

二、美化表单文件上传

看完上面的图片,我们可以知道原来的文件选择风格是最基本的,主要体现在三点:

没有边框,与其他有边框的元素不合拍。选择文件的按钮样式太基础了。选择多个文件后,仅显示总数,但不显示详细选择的文件名。基于几个问题,可以根据需要进行美化

第一点是直接添加边框的样式

第二点需要添加其他元素。可以增加一个按钮(根据需要美化),隐藏原文件框,用JS事件绑定,点击按钮模拟文件框的点击

输入类型='文件'名称='用户图像' id='用户图像'样式=' display: none'输入类型=' button ' id=' ' value='选择一个文件' onclick='文档。getelementbyid ('userimage ')。click()'第三点与第二点类似,必须添加新元素。选择文件后,通过JS获取所选文件信息,并在新元素中显示

思路很简单,但随之而来的问题是,如果有大量选中的文件,新元素占用的空间量就成问题。默认可以显示几个文件,然后可以通过“查看更多文件”查看更多信息

那么另一种想法是,一次选择的文件很多,当你想取消一个文件时,你必须重新选择它。这太麻烦了,所以您需要提供一个操作来立即删除选定的文件

第三,删除选中的文件

要提供选中文件后可以删除的操作,需要提供相关的入口和脚本操作。在这里,我们将围绕这一点做一些分析

1.界面处理

选择一个文件后,我们可以通过删除按钮删除选中的文件,因为会有多个文件,所以需要一个信息模板

!-当前选择的文件列表文件信息模版-脚本类型=' text/template ' id=' file-temp-item-TPL ' span class=' file-temp-item ' style=' { { style } } ' span class=' file-temp-name ' { name } }/span span class=' file-temp-BTN '/span/span/script选中的文件一多,就得再增添一个下拉框做辅助,最多显示5个文件信息,然后通过下拉按钮展开下拉框(按钮样式自行设定)

这里5个文件间的位置计算的不是很到位,主要是这段代码,可以自行设定

//计算每一项坐标左、右占宽widthleft=i===0?2 : 2 I *(100/FileTemplen);宽度=100/文件模板n-2;下拉列表里面的每一项也是一个模版

!-查看更多文件文件信息模版-脚本类型=' text/template ' id=' file-more-item-TPL ' lispan class=' file-item-more-name ' { name } }/span span class=' file-item-more-BTN '/span/Li/脚本以下为初始的超文本标记语言结构

表单名称='form' id='form '方法='post '操作=' FileTest。PHP ' enctype=' multipart/form-data '!-输入类型='数字'名称='numberTest '值='100' -输入类型=“文件”名称='fileTest[]' id='fileTest '倍数!-当前选择的文件列表(最多显示5条)- span class='file-temp'/span!-查看更多文件-ul class=' item-more '/ul put type=' button ' class=' BTN BTN-success ' id='上传BTN ' value='上传p类='上传-提示'文件上传成功/p/表单以下为全部半铸钢钢性铸铁(铸造半钢)样式

链接rel='样式表type=' text/CSS ' href=' bootstrap。量滴CSS ' style type=' text/CSS ' html { font-family : Arial;}表单{ margin: 50px auto宽度: 400像素;}输入{ width : 300 pxpadding : 4px } # uploadBtn { margin-top :-3px;左边距左: 5px宽度: 60px高度: 30pxfont-weight:粗体;font-size : 12px} # FileTest { display : inline-block;border: 1px固体# cccborder-radius : 3px;} .文件-温度{位置:相对;显示器:无;宽度: 300像素;高度:31px }。文件-temp-item {位置:绝对;top: 4pxheight: 24px }。项目-更多-BTN {显示:内嵌块;绝对位置:top: 18px右: 0.5%;宽度: 10px高度: 10pxcolor : # 777 cursor :指针;} .项目-更多-BTN :悬停{边框-顶部-颜色: # AAA} .file-temp-name { display : inline-block;飞越:隐藏;宽度: 90%;高度: 26pxpadd : 2px 15px 2px 5pxborder-半径: 2px背景-color : # eaea 3;文本-飞越:省略号;空白: nowrap} .文件-温度-BTN {绝对位置:显示器:内联块;top : 4px right : 11%;宽度: 18px高度: 18px线高: 18px文本对齐:中心;border: 1px固体# ddd背景色: # CCC边界半径: 50%;color : # ffffont-size : 18px;光标:指针;} .item-more { position :绝对值;溢出-y:自动;显示器:无;左填充: 0;宽度: 300像素;最大高度: 150像素;列表样式:无;} .项目-更多li {相对位置:padding: 5pxborder: 1px固体# cccborder-top:无;} .项目-更多李:悬停{背景色: # f5f 5 F9} .文件项更多名称{ display : inline-block;宽度: 90%;飞越:隐藏;文本-飞越:省略号;空白: nowrap} .文件-项目-更多-BTN {绝对位置:显示器:内联块;top: 8px右: 2%;宽度: 18px高度: 18px线高: 18px文本对齐:中心;border: 1px固体# ddd背景色: # DDD;边界半径: 50%;color : # ffffont-size : 18px;光标:指针;} .文件-项目-更多-BTN :悬停{背景色: # CCC} .上传提示{ display : none margin : 50px自动;文本对齐:中心;font-size : 12px} /style2 .脚本的处理

下面,着重介绍射流研究…脚本的处理

要获取到选中文件的信息,自然想到用价值属性,但通过文件项的价值只能获取到一个文件路径(第一个),无论有没有多个的

无多个的

输入类型更改控制台上的文件。日志(这个。值);'

有多个的

输入类型=“文件”在change=“控制台”上有多个。日志(这个。值);'

既然直接通过价值获取不到所有选中的文件信息,只能寻求其他途径。

1)文件列表

获取选中的文件信息,还可以用文件列表对象,这是在HTML5中新增的,每个表单文件项都有个文件属性,里边存储这选中的文件的一些信息

输入类型=“文件”多个onchange=' console。日志(这个。文件);”选中两个文件后,查看文件信息

文件列表对象看起来是个类数组,有长度属性。所以我们应该可以通过修改或删除相关的项来自定义我们选择的文件(注意其实这是不能修改的,且继续看下去)

如果我选择两个文件并想删除第二个项目,请使用“拼接”删除它,然后

输入类型='file '多个on change=' console . log(array . prototype . splice . call(this . files,1,1));'

报错,可见FileList的length属性是只读的,可以直接修改为可写可配置

object . defineperoperty(FileList . prototype,' length ',{writable: true,configuration ble : true });配置后,长度可以修改。乍一看,拼接被认为是有效的。但是,输出后,FileList对象的内容保持不变,仍然是两个项目

查阅了一些资料,了解到浏览器为了安全起见,将FileList对象的内容设置为不可更改,只能手动留空,不能修改内容

因此,解决方案是添加一个数组,最初复制FileList对象的文件内容,然后通过这个可变数组对其进行修改

//保存并更新所选文件var curFiles=[];//选择文件,然后var files=this.filesif(files . files . length){//原FileList对象无法更改,所以给curFiles提供下一个修改数组。prototype.push.apply (Curfiles,files);}如果点击删除叉号,可以直接更新文件信息数组

var name=$(this)。prev()。text();//删除文件curfiles=curfiles.filter(函数(文件){returnfile.name!==名称;});这样就解决了更新文件信息的问题,然后就可以上传文件了

点击文件上传,如果直接调用$ form . submit();上传的文件信息仍然是初始的FileList对象,不能满足我们的自定义需求,所以需要通过Ajax提交

那么,如何在后台提供文件对象呢?

2)表单数据

HTML5引入了一个新的表单对象FormData,可以生成一个表单对象,从中我们可以获取/设置键值对信息并提交给后台

参考MDN的FormData使用方法,我们可以添加各种类型的数据,并使用ajax提交它们

var Oymform=new form data();omiform . append(' username ',' Groucho ');omiform . append(' account num ',123456);//数字123456会立即转换为字符串“123456”。//file inputrement已经包含用户选择的文件omiform . append(' user file ',file inputrement . files[0]);var oFileBody='a id='a'b id='b '嘿!/a ';//blob对象var o blob=new blob ([ofilebody],{type:' text/XML'})中包含的文件内容;omiform . append(' web master file ',ObLob);var OReq=new XMLHttpRequest();oReq.open('POST ',' http://foo.com/submit form . PHP ');oreq . send(Omeform);您也可以使用JQ封装的ajax,但是要注意将processData和contentType属性设置为false,以防止JQ不加区别地解析文件格式

var FD=new FormData(document . getelementbyid(' file info '));//使用表单作为初始项fd.append('自定义域','这是一些额外的数据');$ .ajax ({url:' stash.php ',type:' post ',data:fd,processdata3360 false,//告诉jQuery不要处理发送的数据Content Type 3360 false//告诉jQuery不要设置Content-Type请求头});这里有几点需要注意:

1)FormData 1)中的属性值接受单个文件的信息,不能是复合对象。可能是暧昧,看看

var FD=new FormData($(“# form”)[0]);fd.append('myFileTest ',curFiles);$ files=$ _ REQUEST[' MyFileTest '];var _ dump($ file);使用PHP接收传输的数据,数据直接转换成字符串,而不是文件对象

CurFiles是一个文件对象,那么PHP应该使用$_FILES来接收信息吗?尝试使用$ FIles=$ _ FILES[' my FILEtest '];

直接有问题,意味着不能这样处理。有必要逐一拆解curFiles的内容,即单个文件信息

var FD=new FormData($(“# form”)[0]);for (var i=0,j=curFiles.lengthI j;i) {fd.append('myFileTest[]',curFiles[I]);} $ FIles=$ _ FILES[' MyFILETest '];var _ dump($ file);

成功接收文件后,您可以根据需要操作文件

2)后端获取文件信息时,直接通过原来的$_FILES获取,其他一般信息通过$_REQUEST获取

替换为$ files=$ _ REQUEST[' MyFileTest '];试试看,这只是一个找不到我的文件测试的问题

提交常规文件之前,请尝试添加它们

var FD=new FormData($(“# form”)[0]);for (var i=0,j=curFiles.lengthI j;i) {fd.append('myFileTest[]',curFiles[I]);}fd.append('myTest ',[1,2,3]);$ FIles=$ _ FILES[' MyFILETest '];$ test=$ _ REQUEST[' MyTest '];var _ dump($ test);var _ dump($ file);

3)如果需要上传多个文件,需要在文件项的文件后面加上【】,表示是多文件数组,用于后端处理分析

fd.append('myFileTest[]',curFiles[I]);如果没有后面的[],连续追加会直接覆盖原来的,后端得到的最后一项只是最后一个追加条目

4)不要在JQ ajax中直接实例化FormData对象,这会导致问题

直接在数据属性中生成FormData对象会被JQ忽略,所以后端得不到任何信息

混合表单项目的简单示例:

在表单处理中,我们经常上传文件和提交其他基本项目,并且简单地添加一个输入项目来查看处理是否成功

输入类型='数字'名称='数字测试'值=' 100 '

?PHP $ FIles=$ _ FILES[' my FILEtest '];$ test=$ _ REQUEST[' NumberTest '];echo JSON _ encode(array(' len '=count($ files[' name ']),' num '=$ test));

以下是所有的JS脚本:

脚本类型='text/javascript'/***向文件列表元素中添加相应的文件项* @param {Array}文件当前的文件列表数组对象*/function addItem(files){ var file tempitemtpl=$(' # file-temp-item-TPL ').html(),fileMoreItemTpl=$(' # file-more-item-TPL ').html()htmlTemp=[],htmlMoreTemp=[],//文件列表中各文件坐标位置及所占空间左=2,宽=100,//最多取前5个文件fileTempLen=files.length 5?5 :个文件for (var i=0,j=files.lengthI ji) {//当i 4,即第6个文件开始if(I ^ 4){ HTMl MoreTemp。push(FileMoreItemTPl。替换(' { { name } } '),文件[i].姓名));继续;}//计算每一项坐标左、右占宽widthleft=i===0?2 : 2 I *(100/FileTemplen);宽度=100/文件模板n-2;html临时文件。push(FileTempItemTPl。替换(' { { style } } '),' left : ' left ' %;宽度:"宽度"%;").替换(“{{name}}”,文件[i].姓名));}//渲染相关元素内容$('.文件-临时')。html(“”)输入类型='文本'样式='背景-color : # fff;class=' form-control ' id=' FileTemp ' readonly ' HTMl Temp。连接(')(文件。长度5?'项目-更多-BTN '查看更多=/span ' : ' ');$('.项目-更多')。html(HTMl MoreTemp。join(" ");}//保存当前选择的(更新后)文件列表var curFiles=[];//初始选择文件时触发$('#fileTest ').change(function(){ var $ this=$(this),$temp=$(').file-temp '),files=this . fileif(files files . length){//原始文件列表对象不可更改,所以将其赋予curFiles提供接下来的修改数组。原型。用力。应用(CurFIles,文件);addItem(curFiles);这个。hide();$temp.css('display ',' inline-block ');}});$(文档)//取消选择某个文件时,在文件列表数组对象中删除这个值,并更新列表。打开('点击','。文件-温度-温度系数.file-item-more-btn ',function() {$(' .上传-提示')。hide();var name=$(this).prev().text();//去除该文件curFiles=curFiles.filter(函数(文件){return file.name!==名称;});//文件列表数组对象长度大于5才显示"更多文件列表"下拉项if (curFiles.length=5) {$(').项目-更多')。hide();}//文件列表数组被清空则重置文件选择表单项if(!curFiles.length) {$('#fileTest ').val(" ")。show();$('.文件-临时')。css('display ',' none ');} else { addItem(curFiles);}console.log(curFiles)})//显示"更多文件列表"下拉项。打开('点击','。item-more-btn ',function() {$(' .上传-提示')。hide();$('.项目-更多')。显示('正常');});//上传操作$('#uploadBtn ').单击(函数(){$(').上传-提示')。hide();//构建表单数据对象var FD=new FormData($(" # form ")[0]);for (var i=0,j=curFiles.lengthI ji) {fd.append('myFileTest[]',curFiles[I]);}$.ajax({url: 'fileTest.php ',type: 'post ',data: fd,processData: false,contentType: false,success : function(RS){ RS=JSON。解析(RS);$('.上传-提示')。addClass('text-success ').removeClass(“文本错误”).文本(rs.len '个文件上传成功,编号项值为rs.num ).show();},错误:函数(err){ } });});/script以上所述是小编给大家介绍的射流研究…实现表单多文件上传样式美化支持选中文件后删除相关项,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

版权声明:JS实现表单多文件上传风格美化 支持选择文件后删除相关项是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。