File控件杂谈
我们通常使用<input type='file'/>来实现网页中文件上传功能,用户可以通过点击file控件选择本地文件,当我们提交包含该控件的表单时,浏览器会向服务器发送用户选中的文件。
看上面的描述,file控件貌似挺强大的,事实上也是这样的。但实际开发中我们也可以挑出file控件的诸多问题:
1、我们可以通过value属性获取用户选择的文件的名称,但出于安全因素,该属性只读,所以也就无法指定默认值。
2、最让我们诟病的是,file控件在不同浏览器上长相迥异。这让我们开发者情何以堪?而且“选择文件”、“浏览…”等字样均无法修改。更可恶的是IE9中file控件类似于输入框的位置需要双击才能触发文件选择。这样的视觉效果与交互体验着实让我们无法接受。
so,目前普遍的解决方案是这样的:
在file控件外面包裹一层容器,并设置其尺寸,通过定位将file控件右侧区域(因为IE9中file控件左侧区域单击无效)显示到目标区域,并为容器设置溢出隐藏。同时,为了让控件可被点击,我们让file处于较高的层并设置透明,只让容器样式可见,以此达到视觉与交互风格的统一。见代码:
<style type="text/css">
.container{
font-family: "microsoft yahei";
position: relative;
width:200px;
height: 80px;
border:1px solid #ccc;/*为了看上去明显*/
overflow: hidden;
line-height: 80px;
font-size: 16px;
text-align: center;
color: #fff;
background-color: #ccc;
border-radius: 4px;
}
.container:hover{
background-color: #eee;
}
#myFile{
position: absolute;
font-size: 300px;
cursor: pointer;
right:0;
top:0;
opacity: 0;
filter: alpha(opacity=0);
}
</style>
<div class="container">
<input type="file" name="myFile" id="myFile" value="" />
选择文件
</div>
这样我们基本上解决了以上所说的问题了。
HTML5到来之前,我们对于file控件可以利用的有用数据也就是value属性了,H5给file控件新增了files属性,该属性包含file控件选择的文件对象的集合,其中包括上次修改时间、名称、大小等信息。这极大地方便了我们开发者,还记得以前在公司做一个项目,要控制上传文件大小的时候还需要借助于flash来实现,否则只能等文件上传到服务端了再判断大小,结果很多时候上传了一个很大的文件,页面加载了半天(向后台传递需要走网络,比较耗时),最后还是告诉我文件过大。试想,这样的体验用户孰忍直视?(PS:IE9不支持files属性)
然而随着技术的发展,我们发现了另外一种可能更符合用户操作习惯的上传文件的方式:拖拽。现在已经有很多网站支持这种方式了。我们看一个演示的例子:
<style>
html,body,div{
margin:0;
padding: 0;
}
#file{
display: none;
}
.up-area{
margin:50px auto;
border: 1px dashed #ccc;
background-color: #eee;
width:600px;
height:400px;
line-height: 400px;
text-align: center;
color: #666;
cursor: pointer;
}
.up-area:hover{
background-color: #ddd;
}
</style>
<input type="file" id="file"/>
<div class="up-area" id="upArea"></div>
<script type="text/javascript">
(function(){
var area= document.getElementById("upArea"),
file = document.getElementById("file");
function uploadFile(fs){
console && console.log(fs);
}
area.onclick = function(){
console && console.log("click");
file.click();
}
file.onchange=function(){
uploadFile(this.files);
}
area.ondragenter = function(e){
this.className = "up-area hover";
e.preventDefault();
}
area.ondragover = function(e){
e.preventDefault();
}
area.ondrop = function(e){
e.preventDefault();
console && console.log("drop");
var dt = e.dataTransfer;
this.className = "up-area";
uploadFile(dt.files);
};
})(); </script>
将文件拖至灰色虚线区域即可查看效果,这里我们主要关注的是div的ondrop事件,我们看到files属性并不是来自file控件,而是dataTransfer对象,我们看到,H5貌似又给我们提供了一种file控件之外的文件上传途径。
那我们继续用用吧!
我们知道,一般的上传文件过程是这样的:点击选择文件或直接将文件拖拽至区域内,触发文件上传,文件异步发送至服务器,待服务器处理完毕,返回消息显示到页面上。
传统的文件上传要实现异步,通常有两种途径(iframe模拟、flash插件)。我们这里都不展示了,我们用FormData,用js创建一个表单对象,并向其中添加表单数据,结合XMLHttpRequest对象将表单异步提交。
看代码:
function uploadFile(fs){
var len = fs.length;
for(var i=0;i<len;i++){
sendFile(fs[i]);
}
}
function sendFile(file){
var xhr = new XMLHttpRequest(),
fd = new FormData();//ie10+ supported
fd.append('file',file);
xhr.onreadystatechange=function(){
if(xhr.readyState == 4 && xhr.status == 200){
consoleDiv.innerHTML += "<br/>" + xhr.responseText;//多文件
}
}
xhr.open("POST",'upload.php');
xhr.send(fd);
}
file.onchange = function(){//file控件属性改变时触发上传
uploadFile(this.files);
}
area.ondrop = function(e){//拖拽区域拖入文件时触发上传
e.preventDefault();
var dt =e.dataTransfer;
uploadFile(dt.files);
}
代码内容比较简单,不再赘述……需要注意的一点就是FormData在IE系列浏览器里,9完全不支持,10和11都是部分支持。
说到这里,与文件上传相关的,我们还想看一个H5新增的对象:FileReader。js创建FileReader对象比较简单:var reader = new FileReader();通过FileReader对象可以访问文件,看一个简单的例子:
var rd = new FileReader();
rd.onload=function(e){
console && console.log(e.target.result);
}
rd.readAsText(file);
以上代码中file参数是一个file对象,可以是File控件的file属性中FileList中的一个,也可以是dataTransfer中files属性中FileList中的一个。
关于FileReader更多的内容同学们可以自己搜寻,先到这里了。由于怕明天会加班,没时间写博,故而提前了一天。
File控件杂谈的更多相关文章
- 混合开发 webview 中file 控件 点击后无反应解决方法
最近在做个项目 ,需要 使用 file 控件上传 图片到服务器 ,在手机浏览器中 可以正常选择照片,但是放到 android 应用中的webview中,file 控件点击后就没有反应. 百度了一番后, ...
- File控件选择图片的时候在Html5下马上预览
页面HTML <div> <img src="@pic.Path" id="img" style="width:200px;heig ...
- input的file 控件及美化
在一些网站进行上传时,当单击了“浏览”按钮之后会弹出[选择文件]的对话框.想要实现这一功能,用input的file控件来实现就好啦~ <!doctype html> <html la ...
- 怎么清除file控件的文件路径
还记得上次做一个文件上传,后来测试告诉我说,如果我要是不选择文件了呢?该怎么办?我说:简单啊,做一个取消按钮不就完事了吗!然后我就想一个file空间做一个取消是多么简单的事,用js处理可是想怎么样就怎 ...
- 为什么Jquery对input file控件的onchange事件只生效一次
今天在做jquery对input file控件的onchange事件进行监听,就一直只生效一次,不知道Jquery为什么对file控件没有做到每次改变触发onchange事件的效果,但是还是有好几种解 ...
- file控件change事件触发问题
最近,项目中需要用到一个图片上传的功能,我用的file控件来选取图片文件,然后利用js读取文件来预览图片,最后再根据用户的操作来决定是否上传文件. 其中碰到了一个奇怪的问题:在选取完第一张图片,并上传 ...
- 美化 input type=file控件
大家都知道input的type=file控件默认样式是不能修改的 可以通过一个小技巧处理下 html: <a href="javascript:;" class=" ...
- 美化type="file"控件
对于type="file"而言是一个不大好看的控件.如果不美化他一下,总感觉自己的网站有些缺乏了美感 上代码: <!DOCTYPE html> <html> ...
- js动态添加file控件
<html></head><script language="javascript" type="text/ecmascript" ...
随机推荐
- windows蓝屏代码大全及常见蓝屏解决方案
对于以下的代码查询建议使用ctrl+F查询,而且很多蓝屏与黑屏的问题多是最近操作引起的,例如更新驱动,安装新的硬件.软件--把相关的配置调到最近的正常状况大多可以解决,确实不行时方可考虑重装系统,解决 ...
- jQuery进行图片预先加载
/** **将图片加载到内存中,在页面任何位置引用的时候,直接从缓存中读取,提升用户的体验,提高网站的流畅度.** **/ <!DOCTYPE html PUBLIC "-//W3C/ ...
- 用Natvis定制C++对象在Visual Studio调试时如何显示
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:用Natvis定制C++对象在Visual Studio调试时如何显示.
- fastjson对Date的处理
对日期的序列化: 一种方法是通过注解 Java代码 ? 1 2 @JSONField (format="yyyy-MM-dd HH:mm:ss") public Date bi ...
- android webview内容压线问题解决方法
最近在使用webview做页面开发,项目上要求webview在获取到焦点的时候需要有边框线,于是添加上了webview的选中效果,但是出现了网页中的内容压选中框的情况.之后给webview添加padd ...
- Redis学习手册(Hashes数据类型)
一.概述: 我们可以将Redis中的Hashes类型看成具有String Key和String Value的map容器.所以该类型非常适合于存储值对象的信息.如Username.Password和Ag ...
- insert into ... on duplicate key update 与 replace 区别
on duplicate key update:针对主健与唯一健,当插入值中的主健值与表中的主健值,若相同的主健值,就更新on duplicate key update 后面的指定的字段值,若没有相同 ...
- Spring MVC 3.0.5+Spring 3.0.5+MyBatis3.0.4全注解实例详解(二)
在上一篇文章中我详细的介绍了如何搭建maven环境以及生成一个maven骨架的web项目,那么这章中我将讲述Spring MVC的流程结构,Spring MVC与Struts2的区别,以及例子中的一些 ...
- Swift之语法1(精简版)
1. Swift简介 2010年的夏天,苹果公司的开发人员Chris Lattne接到了一个特别的任务,为OS X 和iOS平台开发下一代的编程语言,也就是Swift. 苹果公司于2014年WWDC( ...
- 使用nexus创建maven私有仓库
nexus安装 nexus下载 wget https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.11.1-01-bundl ...