关于js拖拽上传 [一个拖拽上传修改头像的流程]


Posted in Javascript onJuly 13, 2011

如今现代的浏览器已经有很多支持拖拽文件读取操作,其优点不再复述。前端时间利用拖拽改进了一下网站的头像上传流程,对其中的要点和实践体会做一点总结。

 先看一下总体视图:
关于js拖拽上传 [一个拖拽上传修改头像的流程]
1、 文件拖拽接受区域要有明显的标示,并且要尽可能的大(由于版面的原因,这个界面的拖放盒子并不大)。可以用虚线框盒子等样式吸引用户拖拽文件。最好有明显的文字提示和图标配合。

2、 在交互体验上当文件拖入浏览器窗口时,可以用拖放区变换背景颜色等向用户发起放置操作邀请。
实现代码:

doc.bind({ 
'dragenter':function(e){ 
$("#brsbox").addClass("dragbrowse"); 
dropbox.addClass("shine"); 
return false; 
}, 
'dragleave':function(e){ 
dropbox.removeClass("shine"); 
return false; 
}, 
'drop':function(e){ 
stopdft(e);} 
}); 
dropbox.bind({ 
'dragenter':function(e){ 
dropbox.addClass("candrop"); 
stopdft(e);}, 
'dragleave':function(e){ 
dropbox.removeClass("candrop"); 
stopdft(e);}, 
'dragover':function(e){ 
stopdft(e);}, 
'drop':function(e){ }

对于不支持拖拽的浏览器:

可惜的是 某些浏览器并不支持文件拖拽读取,这其中包括IE9等较现代的浏览器。所以我们必须为不支持拖拽的浏览器准备普通文件浏览上传作为备用方案。
当不支持拖拽文件读取时,界面如下:

 关于js拖拽上传 [一个拖拽上传修改头像的流程]

实现检测的代码如下:

it.detectDragable = function(){ 
filedrag = !!window.FileReader; 
if(!filedrag) return; 
$("#avtcnt").addClass('dragable');

文件放置时的处理:

 

 关于js拖拽上传 [一个拖拽上传修改头像的流程]

 文件放置到可接受区域时,请注意这时候无论你拖放在鼠标上的文件是单个还是多个,在浏览器和操作系统之间传送的e.dataTransefer.files总是复数。也就是多个文件。这也就意味着你需要循环处理鼠标上所携带的文件。
代码如下:

dropdom.addEventListener('drop',function(e){ 
it.handlefile(e.dataTransfer.files); 
stopdft(e);},false); }; 
it.handlefile = function(files){ 
var noimg = 0; 
for(var i=0; i<files.length; i++){ 
var file = files[i]; 
if(!file.type.match(/image*/)){ 
noimg ++; 
if(noimg ==files.length){ 
QSL.optTips('请选择jpg, png, gif 等格式的图片'); 
return false; 
} 
continue; 
} 
var reader = new FileReader(); 
reader.onload = function(e){ 
var img = document.createElement('img'); 
img.src = reader.result; 
setTimeout(function(){ 
it.imgSize = { 
w:img.width, 
h:img.height 
}; 
},500); 
dropdom.innerHTML=""; 
img.className ='localimg'; 
it.imgData = reader.result; 
dropdom.appendChild(img); 
imagedata.empty().val(reader.result); 
dropbox.addClass("droped"); 
clearner.show(); 
}; 
reader.readAsDataURL(file); 
}

处理拖拽到浏览器的文件

其中 stopdft(e) 是为了防止浏览器默认操作,不以浏览器打开文件。而转由脚本来处理拖放的文件。
这个流程中,我们需要的是图片文件,所以便利操作 e.dataTransfer.files 对象,查找类型为image的文件。
如果没有,则会提示。

读取文件的关键代码:
var reader = new FileReader();

reader.onload = function(e){
var img = document.createElement('img');
img.src = reader.result;
};
reader.readAsDataURL(file);
本例中我们需要读取图片的高度和宽度属性。所以我们做了如下操作
setTimeout(function(){
it.imgSize = {
w:img.width,
h:img.height
};
},500);
虽然是本地文件读取,但是仍然要延时来保证图片确实读取完毕。否则在某些浏览器中会取不到宽高的值。(可否有其他更简便方法?望指出)

删除现有图片,重置拖拽区域:
浏览读取完本地图片之后,要给用户提供删除和重置的选项。(如果是直接上传当然更简便)

it.resetDropbox = function(){ 
dropbox.attr("class","dropbox") 
.empty() 
.text("将文件拖拽至此区域"); 
imgData = ''; 
it.imgData = ''; 
it.imgSize = {w:0,h:0}; 
picsub.removeClass("uploading") 
.find("button").removeAttr("disabled") 
.text("上传"); 
imagedata.val(''); 
clearner.hide();

重置拖拽区域

到这里拖放读取文件的流程基本结束。
利用拖放,读取本地文件的其他优点:
普通的上传更改图片流程是:选择图片-上传图片-上传成功-服务器返回图片-客户端浏览效果
而如果利用拖放读取本地文件则可省去服务器返回 图片的步骤,直接利用reader.result返回的数据。
这样就节省了从服务器读取图片的延迟,并且节省了往返的数据流量。所以只需确认服务器端图片上传成功,图片预览调取本地数据即可:
代码:

function initImageCrop(url){ 
var t = document.getElementById("target"), 
p = document.getElementById("preview"), 
b = browseImage, 
s = [], 
ts = []; 
if(url=='data'){ 
t.src = b.imgData; 
p.src = b.imgData; 
posImage(b.imgSize.w,b.imgSize.h); 
}else{ 
var cutimg = new Image(); 
cutimg.onload = function(){ 
t.src = url; 
p.src = url; 
posImage(cutimg.width,cutimg.height); 
} 
cutimg.src = url;

图片上传成功后的处理

完整DEMO预览(静态文件暂时没有上传成功后的展示(:)
DEMO脚本

Javascript 相关文章推荐
JavaScript Event学习第九章 鼠标事件
Feb 08 Javascript
jQuery初学:find()方法及children方法的区别分析
Jan 31 Javascript
jQuery实现移动 和 渐变特效的点击事件
Feb 26 Javascript
JavaScript判断表单为空及获取焦点的方法
Feb 12 Javascript
JavaScript拖动层Div代码
Mar 01 Javascript
简单实现js菜单栏切换效果
Mar 04 Javascript
jQuery实现验证码功能
Mar 17 Javascript
js实现鼠标单击Tab表单切换效果
May 16 Javascript
解决微信小程序云开发中获取数据库的内容为空的方法
May 15 Javascript
vue router总结 $router和$route及router与 router与route区别
Jul 05 Javascript
微信小程序封装分享与分销功能过程解析
Aug 13 Javascript
详解element-ui 表单校验 Rules 配置 常用黑科技
Jul 11 Javascript
使用 JScript 创建 .exe 或 .dll 文件的方法
Jul 13 #Javascript
JS模拟面向对象全解(二、类型与赋值)
Jul 13 #Javascript
JS模拟面向对象全解(一、类型及传递)
Jul 13 #Javascript
一些实用的jQuery代码片段收集
Jul 12 #Javascript
formValidator3.3的ajaxValidator一些异常分析
Jul 12 #Javascript
在IE浏览器中resize事件执行多次的解决方法
Jul 12 #Javascript
JQuery获取当前屏幕的高度宽度的实现代码
Jul 12 #Javascript
You might like
先进的自动咖啡技术,真的可以取代咖啡师吗?
2021/03/06 冲泡冲煮
php写的带缓存数据功能的mysqli类
2012/09/06 PHP
php 定义404页面的实现代码
2012/11/19 PHP
PHP的error_reporting错误级别变量对照表
2014/07/08 PHP
Laravel 5框架学习之模型、控制器、视图基础流程
2015/04/08 PHP
laravel 执行迁移回滚示例
2019/10/23 PHP
prettify 代码高亮着色器google出品
2010/12/28 Javascript
zShowBox 图片放大展示jquery版 兼容性
2011/09/24 Javascript
jQuery中将函数赋值给变量的调用方法
2012/03/23 Javascript
JS自动缩小超出大小的图片
2012/10/12 Javascript
谈谈JavaScript中的函数与闭包
2013/04/14 Javascript
JQuery判断HTML元素是否存在的两种解决方法
2013/12/26 Javascript
基于jQuery实现二级下拉菜单效果
2016/02/01 Javascript
javascript仿京东导航左侧分类导航下拉菜单效果
2020/11/25 Javascript
常用js,css文件统一加载方法(推荐) 并在加载之后调用回调函数
2016/09/23 Javascript
vue bootstrap小例子一枚
2017/06/09 Javascript
基于ajax和jsonp的原生封装(实例)
2017/10/16 Javascript
解决vue路由后界面没有变化,但是链接有的问题
2018/09/01 Javascript
微信小程序实现登录注册tab切换效果
2020/12/29 Javascript
js实现查询商品案例
2020/07/22 Javascript
原生js实现自定义滚动条
2021/01/20 Javascript
[01:02:03]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS VG
2014/05/26 DOTA
Python中的hypot()方法使用简介
2015/05/18 Python
利用python代码写的12306订票代码
2015/12/20 Python
Python中最大最小赋值小技巧(分享)
2017/12/23 Python
Python推导式简单示例【列表推导式、字典推导式与集合推导式】
2018/12/04 Python
python opencv对图像进行旋转且不裁剪图片的实现方法
2019/07/09 Python
浅谈Django前端后端值传递问题
2020/07/15 Python
Django nginx配置实现过程详解
2020/09/10 Python
Python datetime模块的使用示例
2021/02/02 Python
Pycharm制作搞怪弹窗的实现代码
2021/02/19 Python
销售主管的自我评价分享
2014/01/03 职场文书
2014年社区计生工作总结
2014/11/18 职场文书
法律进社区活动总结
2015/05/07 职场文书
外出学习心得体会范文
2016/01/18 职场文书
解决 Redis 秒杀超卖场景的高并发
2022/04/12 Redis