File杂谈——拖拽上传前传
2015/07/24 · HTML5 ·
拖拽上传
原文出处: 百码山庄
在《File杂谈——初识file控件》一文中,大家曾经对file控件有了伊始的刺探,并且对成立一个视觉和感受一致的file控件做了较为详细的声明,今日大家继续刺探file控件的更加多特点,并拉开出越来越多。
当大家在上传文件时假若每一遍都要上传播服务器才得以预览那些做看上合理其实是不成立的,借使网速慢或图片有题目,那样不但浪费客户时间还要也浪费服务器资源了,上边我们介绍利用js上传图片时当地落成预览,希望此措施对各位有所支持啊。
File杂谈——拖拽异步上传完毕
2015/07/25 · HTML5 ·
异步上传
初稿出处: 百码山庄
在前一篇文章《File杂谈——拖拽上传前传》中自我制作了一个静态的拖拽上传界面,拖拽文件到显示区域释放,能够体现拖入文件的基本音讯。本文将在此基础上越来越加工,打造一个一体化的拖拽上传示例。
拖拽(Drag/Drop)是个格外广阔的功用。你可以引发一个对象,并且拖动到您想放置的区域。
很多javascript都接近已毕了相关的职能,例如,jQueryUI的drag and
drop组件。在HTML5中,拖拽(drag and
drop)成为了正式操作,任何因素都援救。正因为这么些职能太普遍了,所有的主流浏览器都协助那几个操作。
增产属性
在HTML5到来此前,绝大部分情景下利用file控件,我们前端工程师必要的有用信息都只能通过value属性得到的公文名字符串来得到(比如:文件类型、文件的一贯名称等),这些很不便宜,多文件上传的时候就更加勤奋了。别的,我们想不经过任何手段获取上传文件的分寸更是一种奢望。
而是,好在这一体并不曾那么糟,随着HTML5的赶来,file控件上新增了files属性。该属性包蕴了file控件拔取的公文对象集合,每个文件对象涵盖了当前文件的骨干音信(类型、名称、大小)等,那样一来大家再也不用利用正则啊,字符串拆分啊,等等麻烦的办法去取得大家想要的新闻了。下边大家在Chrome的主宰台看下files属性的构造。我的测试方法是如此的:
第一,使用Chrome浏览器随便打开一个网页,然后F12调出开发工具,接着在Console中输入:
JavaScript
document.body.innerHTML = ‘<input type=”file” id=”J_File”>’; var
f = document.getElementById(‘J_File’); f.onchange = function() {
console.log(this.files); };
1
2
3
4
5
|
document.body.innerHTML = ‘<input type="file" id="J_File">’;
var f = document.getElementById(‘J_File’);
f.onchange = function() {
console.log(this.files);
};
|
那会儿页面会被替换成一个file控件,点击选拔一个或多个(多个必要在input标签上平添multiple属性)本地文件,那时change事件将会被触发,控制台将会输出一下数额:
旗帜显著,files属性的值是一个FileList类型的靶子,它和数组类似,同样拥有length属性,而且大家也得以直接行使循环去赢得每一个文本(File)对象(例:取第四个文件就是files[0])。大家继续看每个文件对象中蕴涵的音信,我们常用的name、size、type等周详了,突然觉得好高大上。
不过,我要报告大家的是,大家也不可能无法无天的运用file控件的files属性,因为它在IE9及以下版本的IE浏览器中是不设有的,大家要求运用任何的一手(flash等)来弥补那一个问题,那里就不开展了。
原理
以身作则表达
点击区域接纳文件或直接将文件拖入区域,触发文件上传成效,文件将异步发送到服务器。待服务端处理到位后回去基本音信,在页面中显得。由于服务器容量问题,本示例未做文件保留处理,只是简短的将文件中央音信重回,文件上传的后端具体处理逻辑要求活动补充。
启用拖拽 – draggable属性
非凡不难,只需求将一个要素的拖动属性修改为draggable,那么些因素就协助拖动了,如下所示:
file控件的地点受到胁制
乘胜files属性的面世,file控件的身份显著赢得了很好的升级,可是那并不表示它的位置更加牢固。随着HTML5二来的,并不唯有file控件的files属性。大家早就可以在越来越多的网站上可以见见拖拽上传那些一个风行并且更契合用户作为的相互成效。那里自己先不说拖拽上传功能的得以完成,大家先一起来看看另一种得到FileList对象的措施。
率先,大家需求一个拖拽上传的静态界面,细节不多说,直接上代码:
XHTML
<style> * {margin: 0;padding: 0;} .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” name=”” id=”J_UploadFile”
style=”display: none;”> <div class=”up-area”
id=”J_UploadArea”> 点击那里或拖入文件进行上传 </div>
<script> (function(){ var area =
document.getElementById(“J_UploadArea”), file =
document.getElementById(“J_UploadFile”); function uploadFile(fs) {
console.log(fs); } area.onclick = function() { console.log(‘click’);
file.click(); }; file.onchange = function() { uploadFile(this.files); };
area.ondragenter = function(ev) { this.className = ‘up-area hover’;
ev.preventDefault(); }; area.ondragover = function(ev) {
ev.preventDefault(); }; area.ondrop = function(ev) {
ev.preventDefault(); console.log(‘drop’); var dt = ev.dataTransfer;
this.className = ‘up-area’; uploadFile(dt.files); }; })();
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
<style>
* {margin: 0;padding: 0;}
.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" name="" id="J_UploadFile" style="display: none;">
<div class="up-area" id="J_UploadArea">
点击此处或拖入文件进行上传
</div>
<script>
(function(){
var area = document.getElementById("J_UploadArea"),
file = document.getElementById("J_UploadFile");
function uploadFile(fs) {
console.log(fs);
}
area.onclick = function() {
console.log(‘click’);
file.click();
};
file.onchange = function() {
uploadFile(this.files);
};
area.ondragenter = function(ev) {
this.className = ‘up-area hover’;
ev.preventDefault();
};
area.ondragover = function(ev) {
ev.preventDefault();
};
area.ondrop = function(ev) {
ev.preventDefault();
console.log(‘drop’);
var dt = ev.dataTransfer;
this.className = ‘up-area’;
uploadFile(dt.files);
};
})();
</script>
|
在线Demo。将文件拖入粉青色区域释放便足以在页面上观看文件音讯。
细心的意中人或者曾经意识了,其实大家那边又提供了优化file控件的其它一种艺术——完全选拔另一个标签替代,在该标签的click事件中百尺竿头更进一步触发file控件的click事件,正如下边代码中的: file.click() 。可是,那不是本文的重中之重。
咱俩密切看下边代码中的最后一段,即ondrop的事件处理函数,我们的files对象并不是根源file控件,而是一个叫dataTransfer的事物。那么大家是否足以大胆的臆想,拖拽上传功效其实可以完全抛开file控件独立完结?那里先留个悬念,大家今后再商量。
在上头的案例中大家通过点击来拔取文件从而获得FileList对象,和经过将文件拖拽到肉色区域来取得FileList对象,那二种情势虽不一致,但我们获得的数码确是一模一样的,那足以注解file控件不再独裁,它的身价已经日渐初阶面临勒迫。
1 赞 1 收藏
评论
分为两步:当上传图片的input被触发并选用地面图片之后收获要上传的图样这么些目标的URL(对象URL);把目的URL赋值给事先写好的img标签的src属性即可把图片展现出来。
新的伴儿FormData
咱俩了然,传统的文件上传即使要促成异步的意义,大家会使用iframe去模拟,或使用flash上传插件。可是前几天,大家又认识了一位新成员——FromData,它可以通过js创立表单对象,并得以向该目标中足够表单数据(字符串、数字、文件等)。再组成大家耳熟能详的XMLHttpRequest对象,将表单数据异步提交到服务端,那样大家的题目就一挥而就了。
下边,大家来看下主旨代码:
JavaScript
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(); 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); } //
文件控件爆发变化时,调用uploadFile函数,触发上传作用 file.onchange =
function() { uploadFile(this.files); }; //
在区域内刑释解教拖入文件时,调用文件上传函数 area.ondrop = function(ev) {
ev.preventDefault(); var dt = ev.dataTransfer; uploadFile(dt.files); };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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();
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);
}
// 文件控件发生变化时,调用uploadFile函数,触发上传功能
file.onchange = function() {
uploadFile(this.files);
};
// 在区域内释放拖入文件时,调用文件上传函数
area.ondrop = function(ev) {
ev.preventDefault();
var dt = ev.dataTransfer;
uploadFile(dt.files);
};
|
代码很不难,不再做过多演说。然则此地自己想发表一点私有意见:依据示例大家简单窥见有如此一个题材——假如用户都使用拖拽上传功效,而不应用点击触发File控件选取文件上传,那么File控件完全没有存在的必不可少。联系上文中本身提到的File控件的身份遇到吓唬这一眼光,我胆大的考虑,假设未来的某一项专业中给各类HTMLElement暴光一个增选文件的机能接口,那么拖拽和点选作用将得以集于一个元素之上,到当时File控件的地方恐怕不仅仅是受到威吓,很有可能退出历史舞台!出于File控件视觉效果和互相不联合的角度去考虑,我觉着以上揣测依然有可能的,哈哈~~
虽说示例并未在后端做太多干活儿,我那里依旧以PHP为例,说圣元(Aptamil)下后端该怎么着行事。单从示例而言,我的代码是这么的:
PHP
$file = $_FILES[‘file’]; echo json_encode($file);
1
2
|
$file = $_FILES[‘file’];
echo json_encode($file);
|
能够视为分外简单了。而大家在实际应用中一再还会波及越多更复杂的拍卖逻辑。最起码的大家应该要将tmp_name对应的临时文件移动到大家指定的上传目录吧。当然,这一进度大家就会对文件类型举办判定,大小限制,重命名,数据保存,等等。基本代码:
PHP
$file = $_FILES[‘file’]; $path = ‘./upload’; if ($file[‘size’] >
2000000) { echo ‘{“error”: “1000”, “message”:
“上传文件大小超限,无法超越xxM”}’; } $path .= ‘/file_’ . time() .
‘.png’; // 那里还可能会设有文件数量保存,新旧名称关联等逻辑
move_uploaded_file($file[jquery完成上传图片本地预览效果,拖拽上传前传。’tmp_name’], $path);
1
2
3
4
5
6
7
8
|
$file = $_FILES[‘file’];
$path = ‘./upload’;
if ($file[‘size’] > 2000000) {
echo ‘{"error": "1000", "message": "上传文件大小超限,不能超过xxM"}’;
}
$path .= ‘/file_’ . time() . ‘.png’;
// 这里还可能会存在文件数据保存,新旧名称关联等逻辑
move_uploaded_file($file[‘tmp_name’], $path);
|
<img draggable=”true” />
在此处,大家要求驾驭Javascript里File对象、Blob对象和window.URL.createObjectURL()方法。
一个神奇的办法sendAsBinary
眼前大家聊到的行使FormData来贯彻公文异步上传,在高档浏览器中都能健康运作,没有太大问题。接下来大家此外一个在Firefox完结异步上传的方式。那几个办法,大家又会交到一个新的心上人——FireReader。FileReader是HTML5新增的一个对象,它可以访问用户本地文件,并且可以以差异格式读取文件内容。
拖动中多少的传递
File对象
File里德r基本使用
首先大家来看一下怎样创制一个FileReader实例对象,以及它抱有如何实例方法。在js中创制一个File里德(Reade)r对象很粗略:
JavaScript
var reader = new FileReader();
1
|
var reader = new FileReader();
|
俺们可以因此reader对象访问当地文件,那么reader对象拥有如何大家常用的性能、事件和形式吧?请看之下列表:
拖动的长河中,大家一再须要传递相应的逻辑数据来成功更换的进度,那里最重借使利用dataTransfer对象开展数量传递,上面先看看它的成员:
主意成员:
File对象可以用来得到某个文件的消息,还足以用来读取这一个文件的内容.寻常景况下,File对象是缘于用户在一个input元素上摘取文件后回去的FileList对象,也得以是出自由拖放操作生成的
DataTransfer对象.
事件
- onload :文件成功读完时触发
- onloadend :文件读完时触发,无论成功与否
- onloadstart :开首读取文件时接触
- onprogress :文件读取中,常用来获取读取进度
- onabort :文件读取操作停顿
- onerror :文件读取出错
setData(format, data):把被拖动的数量赋值给dataTransfer对象。
上面来看收获FileList对象:
属性
- result :读取到的文本内容,当读取操作完结后生效
- readyState :File里德(Reade)r对象的当下境况
- error :出错时的错误音信
format:一个String型参数,指定被拖动数据的序列。该参数取值可以是“Text”(文本类型)和“URL”(URL类型)。该参数是高低写非亲非故的,所以传入”text”与”Text”是同等的。
data:一个变体类型参数,指定被拖动的数量。该数据足以是文本,图片路径,URL等等。
该函数有Boolean类型的重返值,true表示数据成功加到dataTransfer中,false代表不成功。若是急需,可以经过那个参数来支配是或不是合宜继续执行某些逻辑。
代码如下
方法
- abort :中断文件读取操作
- readAsBinaryString :将文件内容读取为二进制格式
- readAsDataURL :将文件内容读取为DataURL格式,经常所说的base64格式
- readAsText :将文件内容读取为文本
如上就是File里德r对象最常用的始末,下边大家先看一个小例子:
JavaScript
var rd = new FileReader(); rd.onload = function(ev) {
console.log(ev.target.result); }; rd.readAsText(file);
1
2
3
4
5
|
var rd = new FileReader();
rd.onload = function(ev) {
console.log(ev.target.result);
};
rd.readAsText(file);
|
上述代码中的file参数是一个file对象,可以使File控件的files属性中FileList的一个,也得以是dataTransfer中files属性中FileList的一个。
getData(format):获取dataTransfer中存放的拖动数据。
复制代码
FileReader + sendAsBinary落成异步上传
认识了Fire里德r,下边我们来看一下在Firefox中怎么着使用File里德r和XMLHttpRequest的sendAsBinary方法达成文件异步上传。主题代码如下:
JavaScript
function sendByBinary(file) { var xhr = new XMLHttpRequest(), reader =
new FileReader(); xhr.onreadystatechange = function() { if
(xhr.readyState == 4 && xhr.status == 200) { consoleDiv.innerHTML +=
‘<br>’ + xhr.responseText; } }; xhr.overrideMimeType(‘text/plain;
charset=x-user-defined-binary’); xhr.open(‘POST’, ‘./upload.php’);
reader.onload = function(ev) { // 将二进制内容发送至服务端
xhr.sendAsBinary(ev.target.result); }; // 将文件内容读取为二进制格式
reader.readAsBinaryString(file); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
function sendByBinary(file) {
var xhr = new XMLHttpRequest(),
reader = new FileReader();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
consoleDiv.innerHTML += ‘<br>’ + xhr.responseText;
}
};
xhr.overrideMimeType(‘text/plain; charset=x-user-defined-binary’);
xhr.open(‘POST’, ‘./upload.php’);
reader.onload = function(ev) {
// 将二进制内容发送至服务端
xhr.sendAsBinary(ev.target.result);
};
// 将文件内容读取为二进制格式
reader.readAsBinaryString(file);
}
|
代码很简短,跟FormData的法门大多,大家跟着看服务端将什么收获POST过去的文本内容(以PHP为例):
PHP
// 方法一,这些措施要求php.ini开启帮助 $content =
$GLOBALS[‘HTTP_RAW_POST_DATA’]; //
方法二,不须要php.ini设置,内存压力小 $content =
file_get_contents(‘php://input’);
1
2
3
4
5
|
// 方法一,这个方法需要php.ini开启支持
$content = $GLOBALS[‘HTTP_RAW_POST_DATA’];
// 方法二,不需要php.ini设置,内存压力小
$content = file_get_contents(‘php://input’);
|
故而综合起来相比较有限支撑的法门:
PHP
$content = $GLOBALS[‘HTTP_RAW_POST_DATA’]; if (empty($content)) {
$content = file_get_contents(‘php://input’); } echo $content; //
输出文件内容
1
2
3
4
5
|
$content = $GLOBALS[‘HTTP_RAW_POST_DATA’];
if (empty($content)) {
$content = file_get_contents(‘php://input’);
}
echo $content; // 输出文件内容
|
俺们暂且不说sendAsBinary那种方法当下只有Firefox援助,单从服务器得到文件内容后该怎么处理的话,那种艺术明显并未行使FormData的主意有优势。因为服务端仅仅得到了文件内容,并没有文件类型和分寸等音信,对有些限量逻辑和文件存储的兑现很不协调。
1 赞 2 收藏
评论
format意义与setData中的一样,取值可以是”Text”(文本类型)和”URL”(URL类型)。
<script type=”text/javascript” src=”jquery.js”></script>
clearData(format):移除指定项目标数额。
<input id=”upload” type=”file”>
<img id=”preview” src=””>
那里的format除了上边可以指定的”Text”(文本类型)和”URL”(URL类型)外,还能取下列值:file
<script type=”text/javascript”>
$(‘#upload’).change(function(){
// 获取FileList的第四个因素
alert(document.getelementbyid(‘upload’).files[0]);
});
</script>
- 文件,html – html元素,image – 图片。
这些点子能够用来去采用性的拍卖拖动的数据类型。
Blob对象
属性成员:
一个Blob对象就是一个含有有只读原始数据的类公事对象.Blob对象中的数据并不一定得是JavaScript中的原生方式.File接口基于Blob,继承了Blob的功用,并且伸张协助了用户电脑上的当地文件.
effectAllowed:设置或获取数据源元素中的数据可以举办的操作。
咱俩想要得到的对象URL实际上固然从Blob这些目的得到的,因为File的接口继承Blob。下边就来把Blob对象转换成URL:
属性类型为字符串,取值范围如下:
“copy”-复制数据.
“link”-链接数据.
“move”-移动多少
“copyLink”-复制或链接数据,由目的对象来确定。
“copyMove”-复制或活动多少,由目标对象来规定。
“linkMove”-链接或运动数据,由目的对象来规定。
“all”-所有的操作都是协助的。
“none”-禁止拖动。
“uninitialized”-默许值,采取默许的行事。
注意设置effectAllowed为none未来,拖动是禁止的,不过鼠标形状仍然显得没有可拖动的目标的形状,假使想不出示这一个鼠标形状,则须求将window的event事件的特性returnValue设置为false。
代码如下
dropEffect:设置或得到拖动的靶子上同意的操作以及有关的鼠标形状。
复制代码
属性类型为字符串,取值范围如下:
“copy”-鼠标突显为复制时的形状;
“link”-鼠标呈现为连续的形象;
“move”-鼠标突显为活动的模样。
“none”(默许值)-鼠标呈现为没有拖动的形态。
effectAllowed指定了数据源辅助的操作,所以一般在ondragstart事件中指定。dropEffect指定了拖动放置的对象匡助的操作,所以与effectAllowed合营,常常在拖动的指标上的
ondragenter, ondragover和ondrop等事件中运用。
<script type=”text/javascript”>
var f = document.getelementbyid(‘upload’).files[0];
var src = window.URL.createObjectURL(f);
document.getElementById(‘preview’).src = src;
</script>
files:重返拖动的公文的列表FileList。
types:ondragstart中发送的数码(被拖动的数码)类型的列表。
一个比较完整的实例
dataTransfer对象的存在,使得在拖动的数据源和目的元素之间传递逻辑数据变成了可能。日常大家运用setData方法在数码源元素的ondragstart事件中提供数据,然后再目的元素中,使用getData方法获取数据。
代码如下
拖动中触发的风浪
上边是三次拖拽会时有暴发的风云,基本上事件的触及顺序也就是底下的逐一:
复制代码
dragstart:要被拖拽的因素开端拖拽时接触,这一个事件目的是被拖拽元素。
drag:拖拽元素时接触,这些事件目的是被拖拽元素。
dragenter:拖拽元素进入目标元素时接触,这么些事件目的是目标元素。
dragover:拖拽某元素在对象元素上活动时接触,那一个事件目的是目的元素。
dragleave:拖拽某元素离开目的元素时接触,那一个事件目标是目的元素。
drop:将被拖拽元素放在目的元素内时触发,那一个事件目的是目的元素。
dragend:在drop之后触发,就是拖拽完结时触发,这几个事件目的是被拖拽元素。
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“;
<html xmlns=”;
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″
/>
<title>HTML5 Upload</title>
<style type=”text/css”>
#destination{
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(true,sizingMethod=scale);
}
</style>
基本上事件的参数event都会传来相关的因素,能够很便宜的开展局地修改。那里,大家并不需求处理每个事件,常常只需求挂接主要的多少个事件即可。
<!–<script type=”text/javascript”
src=”;
<script type=”text/javascript”
src=”;
<script type=”text/javascript”>
//处理file input加载的图形文件
$(document).ready(function(e) {
//判断浏览器是还是不是有File里德r接口
if(typeof FileReader ==’undefined’)
{
$(“#destination”).css({‘background’:’none’}).html(‘亲,您的浏览器还不襄助HTML5的File里德r接口,不能采纳图片本地预览,请更新浏览器获得无限体验’);
//即使浏览器是ie
if($.browser.msie===true)
{
//ie6直接用file input的value值本地预览
if($.browser.version==6)
{
$(“#imgUpload”).change(function(event){
//ie6下如何做图片格式判断?
var src = event.target.value;
//var src = document.selection.createRange().text; //选中后
selection对象就生出了 这几个目的只适合ie
var img = ‘<img src=”‘+src+'” width=”200px” height=”200px”
/>’;
$(“#destination”).empty().append(img);
});
}
//ie7,8施用滤镜本地预览
else if($.browser.version==7 || $.browser.version==8)
{
$(“#imgUpload”).change(function(event){
$(event.target).select();
var src = document.selection.createRange().text;
var dom = document.getElementById(‘destination’);
//使用滤镜 成功率高
dom.filters.item(‘DXImageTransform.Microsoft.AlphaImageLoader’).src=
src;
dom.innerHTML = ”;
//使用和ie6相同的法门 设置src为相对路径的法门 有些图片无法显示效果没有利用滤镜好
/*var img = ‘<img src=”‘+src+'” width=”200px” height=”200px”
/>’;
$(“#destination”).empty().append(img);*/
});
}
}
//固然是不协理FileReader接口的低版本firefox 可以用getAsDataURL接口
else if($.browser.mozilla===true)
{
$(“#imgUpload”).change(function(event){
//firefox2.0尚无event.target.files这一个属性 就像是ie6那样采取value值
可是firefox2.0不接济相对路径嵌入图片 扬弃firefox2.0
//firefox3.0上马具有event.target.files这么些属性
并且开头支持getAsDataURL()那个接口 从来到firefox7.0说尽
但是事后都可以用HTML5的FileReader接口了
if(event.target.files)
{
//console.log(event.target.files);
for(var i=0;i<event.target.files.length;i++)
{
var img = ‘<img
src=”‘+event.target.files.item(i).getAsDataURL()+'” width=”200px”
height=”200px”/>’;
$(“#destination”).empty().append(img);
}
}
else
{
//console.log(event.target.value);
//$(“#imgPreview”).attr({‘src’:event.target.value});
}
});
}
}
else
{
// version 1
/*$(“#imgUpload”).change(function(e){
var file = e.target.files[0];
var fReader = new FileReader();
//console.log(fReader);
//console.log(file);
fReader.onload=(function(var_file)
{
return function(e)
{
$(“#imgPreview”).attr({‘src’:e.target.result,’alt’:var_file.name});
}
})(file);
fReader.readAsDataURL(file);
});*/
//单图上传 version 2
/*$(“#imgUpload”).change(function(e){
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(e){
//displayImage($(‘bd’),e.target.result);
//alert(‘load’);
$(“#imgPreview”).attr({‘src’:e.target.result});
}
reader.readAsDataURL(file);
});*/
//多图上传 input file控件里指定multiple属性 e.target是dom类型
$(“#imgUpload”).change(function(e){
for(var i=0;i<e.target.files.length;i++)
{
var file = e.target.files.item(i);
//允许文件MIME类型 也得以在input标签中指定accept属性
//console.log(/^image/.*$/i.test(file.type));
if(!(/^image/.*$/i.test(file.type)))
{
continue; //不是图片 就跳出这一回巡回
}
//实例化FileReader API
var freader = new FileReader();
freader.readAsDataURL(file);
freader.onload=function(e)
{
var img = ‘<img src=”‘+e.target.result+'” width=”200px”
height=”200px”/>’;
$(“#destination”).empty().append(img);
}
}
});
//处理图片拖拽的代码
var destDom = document.getElementById(‘destination’);
destDom.addEventListener(‘dragover’,function(event){
event.stopPropagation();
event.preventDefault();
},false);
destDom.addEventListener(‘drop’,function(event){
event.stopPropagation();
event.preventDefault();
var img_file =
event.dataTransfer.files.item(0); //获取拖拽过来的文件信息暂时取一个
//console.log(event.dataTransfer.files.item(0).type);
if(!(/^image/.*$/.test(img_file.type)))
{
alert(‘您还未拖拽任何图片过来,或者你拖拽的不是图表文件’);
return false;
}
fReader = new FileReader();
fReader.readAsDataURL(img_file);
fReader.onload = function(event){
destDom.innerHTML=”;
destDom.innerHTML = ‘<img src=”‘+event.target.result+'”
width=”200px” height=”200px”/>’;
};
},false);
}
});
</script>
</head>
拖动起始 – ondragstart事件
从那几个事件传入的参数含有的音讯相当丰盛,从中可以很便宜的收获到被拖动的元素(event.Target);从中可以安装被拖动数据(event.dataTransfer.setData);所以你可以很有益完成拖动的私自逻辑(当然你绑定的时候也足以传递其余的参数)。
拖动过程中 – ondrag,ondragover,ondragenter和ondragleave事件
ondrag事件的目的是被拖拽元素,寻常这一个事件处理的可比少。ondragenter事件是当拖动进入当前因素时暴发,ondragleave事件是在当拖动离开当前元素时爆发,ondragover事件是在拖动在脚下因素中移动时发出。
这里只须要留意一点,因为默许情状下,浏览器是明令禁止元素drop的,所以为了让要素得以drop,必要在这些函数中回到false或者调用event.preventDefault()方法。如下边的例证所示。
拖动停止 – ondrop,ondragend事件
当可拖动的数量被drop的时候,drop事件触发。drop为止后,dragend事件被触发,那一个事件拔取的也绝对少一点。
<body>
<input type=”file” id=”imgUpload” name=”imgUpload” draggable=”true”
single/> <!–允许file控件接受的文件类型–>
<!–<input type=”file” id=”imgUpload” name=”imgUpload”
accept=”image/*” multiple/>–>
<div id=”destination” style=”width:200px;height:200px;border:1px
solid #000000;”><img src=”nopic.jpg” /></div>
</body>
</html>
看一个简约的例证:
兼容性
<!DOCTYPE HTML>
<html>
<head>
<script type=”text/javascript”>
function allowDrop(ev){
ev.preventDefault();
}
function drag(ev){
ev.dataTransfer.setData(“Text”,ev.target.id);
}
function drop(ev){
var data=ev.dataTransfer.getData(“Text”);
ev.target.appendChild(document.getElementById(data));
ev.preventDefault();
}
</script>
</head>
<body>
<div id=”div1″ ondrop=”drop(event)” ondragover=”allowDrop(event)”></div>
<img id=”drag1″ src=”img_logo.gif” draggable=”true” ondragstart=”drag(event)” width=”336″ height=”69″ />
</body>
</html>
•上述方式适用于chrome浏览器
•如若是IE浏览器可以直接行使input的value来代替src
•网上查看资料有直接选拔File对象的getAsDataURL()方法赢得URL的,现在以此点子都已经打消,类似的还有getAsText()和getAsBinary()方法;
…
文本拖拽
上面的例子已经拔取了dataTransfer的各个情势和总体性,上边再看网上的其它一个妙趣横生的施用:拖拽一个图片到网页上,然后在网页上展示。这些动用使用了dataTransfer的files属性。
<!DOCTYPE HTML>
<html>
<head>
亚洲必赢官网 , <meta charset=”utf-8″>
<title>HTML5拖放文件</title>
<style>
#section{font-family: “Georgia”, “微软雅黑”, “华文中宋”;}
.container{display:inline-block;min-height:200px;min-width:360px;color:#f30;padding:30px;border:3px solid #ddd;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;}
.preview{max-width:360px;}
#files-list{position:absolute;top:0;left:500px;}
#list{width:460px;}
#list .preview{max-width:250px;}
#list p{color:#888;font-size:12px;}
#list .green{color:#09c;}
</style>
</head>
<body>
<div id=”section”>
<p>把你的图形拖到上面的器皿内:</p>
<div id=”container” class=”container”>
</div>
<div id =”files-list”>
<p>已经拖进过来的公文:</p>
<ul id=”list”></ul>
</div>
</div>
<script>
if (window.FileReader) {
var list = document.getElementById(‘list’),
cnt = document.getElementById(‘container’);
// 判断是不是图片
function isImage(type) {
switch (type) {
case ‘image/jpeg’:
case ‘image/png’:
case ‘image/gif’:
case ‘image/bmp’:
case ‘image/jpg’:
return true;
default:
return false;
}
}
// 处理拖放文件列表
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
var t = f.type ? f.type : ‘n/a’,
reader = new FileReader(),
looks = function (f, img) {
list.innerHTML += ‘<li><strong>’ + f.name + ‘</strong> (‘ + t +
‘) – ‘ + f.size + ‘ bytes<p>’ + img + ‘</p></li>’;
cnt.innerHTML = img;
},
isImg = isImage(t),
img;
// 处理获得的图样
if (isImg) {
reader.onload = (function (theFile) {
return function (e) {
img = ‘<img class=”preview” src=”‘ + e.target.result + ‘” title=”‘ + theFile.name + ‘”/>’;
looks(theFile, img);
};
})(f)
reader.readAsDataURL(f);
} else {
img = ‘”o((>ω< ))o”,你传进来的不是图表!!’;
looks(f, img);
}
}
}
// 处理插入拖出职能
function handleDragEnter(evt){ this.setAttribute(‘style’, ‘border-style:dashed;’); }
function handleDragLeave(evt){ this.setAttribute(‘style’, ”); }
// 处理公事拖入事件,幸免浏览器默许事件带来的重定向
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
}
cnt.addEventListener(‘dragenter’, handleDragEnter, false);
cnt.addEventListener(‘dragover’, handleDragOver, false);
cnt.addEventListener(‘drop’, handleFileSelect, false);
cnt.addEventListener(‘dragleave’, handleDragLeave, false);
} else {
document.getElementById(‘section’).innerHTML = ‘你的浏览器不援助啊,同学’;
}
</script>
</body>
</html>
那几个事例中运用了html5中的文件读取API:FileReader对象;该目的提供了下列异步方法用于读取文件:
- FileReader.readAsBinaryString(fileBlob)
以二进制的法门读取文件,result 属性会包罗一个文件的二进制的格式 - FileReader.readAsText(fileBlob, opt_encoding)
以文件的形式读取文件, result
属性将会含有一个文本的文本格式,默认解码参数是 “utf-8”。 - FileReader.readAsDataURL(file)
以URL方式读取文件result 将会包涵一个文件的 DataURL
格式(图片经常用这种方法)。
当使用方面的艺术读取文件后,会接触下列事件:
onloadstart,onprogress,onabort,onerror,onload,onloadend
那一个事件都很简短,需求的时候挂接就可以了。看上边的代码示例:
function startRead() {
// obtain input element through DOM
var file = document.getElementById(‘file’).files[0];
if(file){
getAsText(file);
}
}
function getAsText(readFile) {
var reader = new FileReader();
// Read file into memory as UTF-16
reader.readAsText(readFile, “UTF-16”);
// Handle progress, success, and errors
reader.onprogress = updateProgress;
reader.onload = loaded;
reader.onerror = errorHandler;
}
function updateProgress(evt) {
if (evt.lengthComputable) {
// evt.loaded and evt.total are ProgressEvent properties
var loaded = (evt.loaded / evt.total);
if (loaded < 1) {
// Increase the prog bar length
// style.width = (loaded * 200) + “px”;
}
}
}
function loaded(evt) {
// Obtain the read file data
var fileString = evt.target.result;
// Handle UTF-16 file dump
if(utils.regexp.isChinese(fileString)) {
//Chinese Characters + Name validation
}
else {
// run other charset test
}
// xhr.send(fileString)
}
function errorHandler(evt) {
if(evt.target.error.name == “NotReadableErr”) {
// The file could not be read
}
}
那里也大概说一下:普通的文本下载使用的就是window.open方法,例如:
window.open(”)
实用参考: 法定文档:
一个没错的教程网站:
MSDN帮助:
文件拖拽详述:
文件拖拽并上传:
文件拖拽上传完整例子:
文件下载的事例:
window.open攻略:
window.open参数: