菜单

JS实现表单多文件上传样式美化支持选中文件后删除相关项_javascript技巧_脚本之家

2020年3月14日 - 首页

付出中会平时提到到文件上传的急需,依据职业差异的须要,有两样的文件上传情形。

有简要的单文件上传,有多文本上传,因浏览器原生的文件上传样式及效果的支撑度不算太高,非常多时候我们会对体制进行美化,对效果拓宽宏观。

本文依照八个例证,对多文件的上传样式做了有个别简约的夸口,同一时候协助选择文件后自定义删除相关的公文,最终再上传

小说篇幅较长,先轻松看看图示:

一、文件上传功底

1. 单文书上传

最简便易行的文本上传,是单文件上传,form标签中投入enctype=”multipart/form-data”,form表单中有多少个input[type=”file”]项

2. 多文本上传

1)相近单文件上传,轻易的多文本上传其实就是多多少个input[type=”file”]项

2卡塔尔(قطر‎ HTML5为表单文件项新扩展了三个multiple属性,可以安装完成选用五个公文,如

二、表单文件上传的美化

看了地点多少个图片,可知原生的文书接收项样式是最中央的,首要体以往四个点:

无边框,与任何有边框的成分不联合拍片选取文件的按钮样式太根基选用八个文本后只展现总的数量,未出示详细选拔的文本名基于多少个难题,能够按需对其展开美化

第一点能够直接抬高边框的样式

第二点须要扩张其余因素,能够大幅度增加一个开关,将原本文本框隐蔽,用JS事件绑定,点击按键后模拟文件框的点击

其三点与第二点相似,也得增加新的因素,选拔文件后,通过JS获取选取的公文音讯,并在新的要素中显得出来

想着相当的轻易,但随之而来的主题材料就是,固然当选的文书数量过多,新成分占空间的有些正是个难题,能够暗中认可展现多少个文件,再经过“查看越来越多文件”查见到越多的新闻

跟着其余的主张是,叁次性选中的文本过多,想收回有个别文件时,又得重复接受。这未免太繁缛,所以必要提供即时删除某些选普通话件的操作

三、选粤语件后的去除

要提供选普通话件后可去除的操作,就一定要求提供相关进口及脚本操作,下边围绕那一点来做些深入解析

1. 分界面包车型大巴管理

选取文件后,大家得以由此删除开关删除选中的公文,因为相会世多文件的景观,所以要求贰个消息模版

<span style="{{style}}"><span >{{name}}</span><span >×</span></span>

入选的文件一多,就得再扩充二个下拉框做扶助,最多呈现5个文本消息,然后经过下拉开关张开下拉框

此地5个公文间的职分总括的不是很到位,首假使这段代码,能够活动设定

// 计算每一项坐标left、占宽widthleft = i === 0 ? 2 : 2 + i * ;width = 100 / fileTempLen - 2;

下拉列表里面包车型客车每一种也是一个模板

 <li><span >{{name}}</span><span >×</span></li>

以下为始发的HTML构造

  html { font-family: Arial; } form { margin: 50px auto; width: 400px; } input { width: 300px; padding: 4px; } #uploadBtn { margin-top: -3px; margin-left: 5px; width: 60px; height: 30px; font-weight: bold; font-size: 12px; } #fileTest { display: inline-block; border: 1px solid #ccc; border-radius: 3px; } .file-temp { position: relative; display: none; width: 300px; height: 31px; } .file-temp-item { position: absolute; top: 4px; height: 24px; } .item-more-btn { display: inline-block; position: absolute; top: 18px; right: 0.5%; width: 10px; height: 10px; color: #777; cursor: pointer; } .item-more-btn:hover { border-top-color: #aaa; } .file-temp-name { display: inline-block; overflow: hidden; width: 90%; height: 26px; padding: 2px 15px 2px 5px; border-radius: 2px; background-color: #eaeaf3; text-overflow: ellipsis; white-space: nowrap; } .file-temp-btn { position: absolute; display: inline-block; top: 4px; right: 11%; width: 18px; height: 18px; line-height: 18px; text-align: center; border: 1px solid #ddd; background-color: #ccc; border-radius: 50%; color: #fff; font-size: 18px; cursor: pointer; } .item-more { position: absolute; overflow-y: auto; display: none; padding-left: 0; width: 300px; max-height: 150px; list-style: none; } .item-more li { position: relative; padding: 5px; border: 1px solid #ccc; border-top: none; } .item-more li:hover { background-color: #f5f5f9; } .file-item-more-name { display: inline-block; width: 90%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .file-item-more-btn { position: absolute; display: inline-block; top: 8px; right: 2%; width: 18px; height: 18px; line-height: 18px; text-align: center; border: 1px solid #ddd; background-color: #ddd; border-radius: 50%; color: #fff; font-size: 18px; cursor: pointer; } .file-item-more-btn:hover { background-color: #ccc; } .upload-tip { display: none; margin: 50px auto; text-align: center; font-size: 12px; } 

2. 本子的拍卖

上面,注重介绍JS脚本的拍卖

要拿走到当选文件的音讯,自然想到用value属性,但透过文件项的value只好获取到叁个文书路线,无论有未有multiple

既然如此向来通过value获取不到独具入选的文件新闻,只好寻求别的路径。

1)FileList

获取选中的文书音讯,还足以用FileList对象,这是在HTML5中新扩展的,每一种表单文件项都有个files属性,里边存款和储蓄这选中的公文的一些新闻

选中八个公文后,查看文件音讯

FileList对象看起来是个类数组,有length属性。所以大家应有能够通过修正或删除相关的项来自定义我们采用的文书

假使本身选用了五个文件,想删除第二品种,使用splice删除,则

报错,因此可以见到FileList的length属性是只读的,那直接改革为可写可配备呢

Object.defineProperty(FileList.prototype, 'length', {writable: true,configurable: true});

陈设之后length能改改了,乍一看还感觉splice生效了,然则输出一看,FileList对象内容不改变,仍然是两项

翻看了一些素材后,精通到浏览器为了安全性的杜撰,把FileList对象的故事情节设为了不可改换,只好够手动置空,但不可能改进内容

据此,消除办法是,新扩充多个数组,初阶复制FileList对象的公文内容,之后的改进操作则通过这几个可校勘的数组实行

// 存储更新所选文件var curFiles = []; ...// 选中文件后var files = this.files;if (files && files.length) {// 原始FileList对象不可更改,所以将其赋予curFiles提供接下来的修改Array.prototype.push.apply;}

设若点击了剔除叉叉,能够直接更新文件音讯数组

var name = $;// 去除该文件curFiles = curFiles.filter {return file.name !== name;});

那样一来,更新文件新闻的主题素材获得消除,然后就能够实行理文件件的上传了

点击文件上传,倘若直白调用$form.submit(卡塔尔;
则上传的文书消息仍然为始于的FileList对象,达不到大家自定义的渴求,所以须要用Ajax提交

那正是说,该怎么想后台提供二个文书对象呢?

2)FormData

HTML5引进了表单的新对象FormData,
它能够生成八个表单对象,大家得以向里面赢得/设置键值对音讯,再一并付出给后台

援引MDN的FormData使用格局,大家能够增加各种类型的数量,使用ajax提交

var oMyForm = new FormData();oMyForm.append("username", "Groucho");oMyForm.append; // 数字123456被立即转换成字符串"123456"// fileInputElement中已经包含了用户所选择的文件oMyForm.append("userfile", fileInputElement.files[0]);var oFileBody = 'hey!'; // Blob对象包含的文件内容var oBlob = new Blob([oFileBody], { type: "text/xml"});oMyForm.append("webmasterfile", oBlob);var oReq = new XMLHttpRequest();oReq.open("POST", "http://foo.com/submitform.php");oReq.send;

也可利用JQ的包裹的ajax,可是要用心设置processData和contentType属性为false,防止JQ胡乱拆解分析文件格式

var fd = new FormData(document.getElementById; // 使用某个表单作为初始项fd.append("CustomField", "This is some extra data");$.ajax({url: "stash.php",type: "POST",data: fd,processData: false, // 告诉jQuery不要去处理发送的数据contentType: false // 告诉jQuery不要去设置Content-Type请求头});

那边有多少个要小心的点:

1)FormData中的属性值选拔的是单个文件音讯,无法是复合性的对象。恐怕表意不明,且看

var fd = new FormData;fd.append('myFileTest', curFiles);$files = $_REQUEST['myFileTest'];var_dump;

用PHP选拔传过来的数码,数据却被向来调换来字符串了,非文件对象

curFiles是文件对象,那PHP端是还是不是应有用$_FILES来抽出消息吗,试试换来$files
= $_FILES[‘myFileTest’];

直白出难题了,表明不能那样管理,要求将curFiles内容一项一项拆开,即单个文件消息

var fd = new FormData;for (var i = 0, j = curFiles.length; i < j; ++i) {fd.append('myFileTest[]', curFiles[i]);}$files = $_FILES['myFileTest'];var_dump;

文件吸收接纳成功,接下去就足以按需举行文件的操作了

2)后端获取文件消息的时候,是一贯通过原始$_FILES获取的,其余经常的音信才用$_REQUEST获取

换成$files =
$_REQUEST[‘myFileTest’];试试,直接便是出新找不到myFileTest的主题素材

试跳增多经常的文件再提交

var fd = new FormData;for (var i = 0, j = curFiles.length; i < j; ++i) {fd.append('myFileTest[]', curFiles[i]);}fd.append;$files = $_FILES['myFileTest'];$test = $_REQUEST['myTest'];var_dump;var_dump如果需要multiple的多文件上传,则需要在文件项的文件后添加[]号,表示这是一个多文件的数组,以供后端处理解析fd.append('myFileTest[]', curFiles[i]);

假使未有后边的[],则延续的append会直接覆盖原本的,最后后端获取到的只是最后append进去的项

4)不要一直在JQ的ajax中实例化出多个FormData对象,会出难点

一向在data属性中生成FormData对象,会被JQ忽视,所未来端什么消息也拿不到

混合表单项轻易的事例:

在表单管理中,超级多时候大家会开展文件上传和此外功底项的交给,轻松地多加叁个input项目,看看是或不是管理成功

 count,'num' => $test));?>

以下为整个的JS脚本:

/*** &#21521;&#25991;&#20214;&#21015;&#34920;&#20803;&#32032;&#20013;&#28155;&#21152;&#30456;&#24212;&#30340;&#25991;&#20214;&#39033;* @param {Array} files &#24403;&#21069;&#30340;&#25991;&#20214;&#21015;&#34920;&#25968;&#32452;&#23545;&#35937;*/function addItem {var fileTempItemTpl = $('#file-temp-item-tpl').html(),fileMoreItemTpl = $('#file-more-item-tpl').html()htmlTemp = [],htmlMoreTemp = [],// &#25991;&#20214;&#21015;&#34920;&#20013;&#21508;&#25991;&#20214;&#22352;&#26631;&#20301;&#32622;&#21450;&#25152;&#21344;&#31354;&#38388;left = 2,width = 100,// &#26368;&#22810;&#21462;&#21069;5&#20010;&#25991;&#20214;fileTempLen = files.length &gt; 5 &amp;#63; 5 : files.length;for (var i = 0, j = files.length; i &lt; j; ++i) {// &#24403;i &gt; 4&#65292;&#21363;&#31532;6&#20010;&#25991;&#20214;&#24320;&#22987;if  {htmlMoreTemp.push(fileMoreItemTpl.replace('{{name}}', files[i].name));continue;}// &#35745;&#31639;&#27599;&#19968;&#39033;&#22352;&#26631;left&#12289;&#21344;&#23485;widthleft = i === 0 &amp;#63; 2 : 2 + i * ;width = 100 / fileTempLen - 2;htmlTemp.push(fileTempItemTpl.replace('{{style}}', 'left: ' + left + '%;width: ' + width + '%;').replace('{{name}}', files[i].name));}// &#28210;&#26579;&#30456;&#20851;&#20803;&#32032;&#20869;&#23481;$.html(''+ '&lt;input type="text" style="background-color:#fff;" readonly&gt;'+ htmlTemp.join+ (files.length &gt; 5&amp;#63; '&lt;span title="&#26597;&#30475;&#26356;&#22810;"&gt;=&lt;/span&gt;': ''));$.html);}// &#20445;&#23384;&#24403;&#21069;&#36873;&#25321;&#30340;&#25991;&#20214;&#21015;&#34920;var curFiles = [];// &#21021;&#22987;&#36873;&#25321;&#25991;&#20214;&#26102;&#35302;&#21457;$.change {var $this = $,$temp = $,files = this.files;if (files &amp;&amp; files.length) {// &#21407;&#22987;FileList&#23545;&#35937;&#19981;&#21487;&#26356;&#25913;&#65292;&#25152;&#20197;&#23558;&#20854;&#36171;&#20104;curFiles&#25552;&#20379;&#25509;&#19979;&#26469;&#30340;&#20462;&#25913;Array.prototype.push.apply;addItem;$this.hide();$temp.css('display', 'inline-block');}});$// &#21462;&#28040;&#36873;&#25321;&#26576;&#20010;&#25991;&#20214;&#26102;&#65292;&#22312;&#25991;&#20214;&#21015;&#34920;&#25968;&#32452;&#23545;&#35937;&#20013;&#21024;&#38500;&#36825;&#20010;&#20540;&#65292;&#24182;&#26356;&#26032;&#21015;&#34920;.on('click', '.file-temp-btn, .file-item-more-btn', function.hide.prev;// &#21435;&#38500;&#35813;&#25991;&#20214;curFiles = curFiles.filter {return file.name !== name;});// &#25991;&#20214;&#21015;&#34920;&#25968;&#32452;&#23545;&#35937;&#38271;&#24230;&#22823;&#20110;5&#25165;&#26174;&#31034;&#8220;&#26356;&#22810;&#25991;&#20214;&#21015;&#34920;&#8221;&#19979;&#25289;&#39033;if  {$;}// &#25991;&#20214;&#21015;&#34920;&#25968;&#32452;&#34987;&#28165;&#31354;&#21017;&#37325;&#32622;&#25991;&#20214;&#36873;&#25321;&#34920;&#21333;&#39033;if  {$.show.css;} else {addItem;}console.log// &#26174;&#31034;&#8220;&#26356;&#22810;&#25991;&#20214;&#21015;&#34920;&#8221;&#19979;&#25289;&#39033;.on('click', '.item-more-btn', function.hide.show;// &#19978;&#20256;&#25805;&#20316;$.click {$;// &#26500;&#24314;FormData&#23545;&#35937;var fd = new FormData;for (var i = 0, j = curFiles.length; i &lt; j; ++i) {fd.append('myFileTest[]', curFiles[i]);}$.ajax({url: 'fileTest.php',type: 'post',data: fd,processData: false,contentType: false,success: function {rs = JSON.parse.addClass.removeClass.text(rs.len + '&#20010;&#25991;&#20214;&#19978;&#20256;&#25104;&#21151;, number&#39033;&#20540;&#20026;' + rs.num).show();},error: function;

如上所述是小编给咱们介绍的JS完成表单多文件上传样式美化扶助选中文件后去除相关项,希望对大家有所扶助,假若大家有任何疑问请给笔者留言,作者会及时过来大家的。在那也特别多谢大家对剧本之家网址的支撑!

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图